Martin Fowler has a Money class, который имеет рутину распределения денег. Эта процедура распределяет деньги в соответствии с определенным списком коэффициентов, не теряя при этом значения при округлении. Он распределяет любое остаточное значение по результатам.Доказательство правильности алгоритма распределения денег Фаулера
Например, 100 долл. США, выделенные «отношениями» (1, 1, 1), будут давать (34 долл. США, 33 долл. США, 33 долл. США).
Вот allocate
функция:
public long[] allocate(long amount, long[] ratios) {
long total = 0;
for (int i = 0; i < ratios.length; i++) total += ratios[i];
long remainder = amount;
long[] results = new long[ratios.length];
for (int i = 0; i < results.length; i++) {
results[i] = amount * ratios[i]/total;
remainder -= results[i];
}
for (int i = 0; i < remainder; i++) {
results[i]++;
}
return results;
}
(. Ради этого вопроса, чтобы сделать его проще, я взял на себя смелость заменить типы денег с лонги)
вопрос в том, как я знаю, что это правильно? Все это кажется довольно очевидным, за исключением финальной петли. Я думаю, что для доказательства функция является правильным, было бы достаточно, чтобы доказать, что соотношение справедливо в финале для цикла:
remainder < results.length
Может кто-нибудь доказать?
Скажите, что вы хотите разбить X-число на Y частей. Напомним, что X% Y всегда