Martin Fowler has a Money class có thói quen phân bổ tiền. Quy trình này phân bổ tiền theo danh sách các tỷ lệ đã cho mà không làm mất bất kỳ giá trị nào thông qua làm tròn. Nó lây lan bất kỳ giá trị còn lại trên kết quả.Chứng minh rằng thuật toán phân bổ tiền của Fowler là chính xác
Ví dụ: $ 100 được phân bổ theo "tỷ lệ" (1, 1, 1) sẽ mang lại ($ 34, $ 33, $ 33).
Đây là allocate
chức năng:
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;
}
(. Vì mục đích của câu hỏi này, để làm cho nó đơn giản hơn, tôi đã lấy sự tự do thay thế các loại tiền với chờ đợi)
Các câu hỏi là, làm thế nào để tôi biết nó là chính xác? Tất cả có vẻ khá rõ ràng, ngoại trừ vòng lặp cuối cùng. Tôi nghĩ rằng để chứng minh chức năng là chính xác, sẽ đủ để chứng minh rằng mối quan hệ sau đây là đúng trong vòng lặp cuối cùng:
remainder < results.length
Có ai chứng minh điều đó không?
Giả sử bạn muốn chia số X thành các phần Y. Lời nhắc là X% Y luôn là