[英]Overflow of integer in Java
我在接受采訪時被問到這個問題。 我被要求計算數字x1,x2,x3,... xn的平均值
class Iterator {
bool hasNext;
int getNext();
}
//所以它歸結為這樣的事情:
double average (Iterator & it) {
double average = 0;
double sum = 0;
int len = 0;
while (it.hasNext == true) {
sum += it.getNext();
}
if (len > 0)
average = sum / len;
}
采訪者說清單大小不明,而且可能非常大,所以總和可能會溢出。 他問我如何解決溢出問題,我通過跟蹤我們如何超過最大數量等來回答,他說了一些關於推入堆棧的事情,平均值和長度,我從來沒有真正理解他的解決方案通過推動這些2變量成某種列表? 有人有線索嗎?
我不知道使用堆棧,但在代數的幫助下,我們可以使用舊的平均值推導出新平均值的公式。
假設您已經平均了n - 1
項目,並且您在oldAvg
有平均值。
oldAvg =(x 1 + x 2 + .. + x n - 1 )/(n - 1)
新的平均值將由newAvg
表示:
newAvg =(x 1 + x 2 + .. + x n - 1 + x n )/ n
通過一些代數操作,我們可以使用舊平均值表示平均值的新平均值,以及下一個項目。
newAvg =(x 1 + x 2 + .. + x n - 1 )/ n + x n / n
=((n - 1)/(n - 1))*(x 1 + x 2 + .. + x n - 1 )/ n + x n / n
= oldAvg / n *(n - 1)+ x n / n
這可以通過在乘以n - 1
之前除以n
來避免溢出。 然后你所要做的就是添加下一項x n除以n
。
第一個循環將平均值設置為等於第一個元素,但每個后續循環將使用上面的公式來推導新的平均值。
n++;
newAvg = oldAvg / n * (n - 1) + it.next() / n;
他可能指的是您不需要所有術語來計算平均值,而是可以跟蹤移動平均線 。 這可以與迄今為止考慮提出的術語總和的術語數一起使用。
由於總數可能太大而無法長時間存儲,因此您需要使用類似BigInteger
東西來保存總數。
如果您進一步簡化rgettman的公式,您將得到以下信息:
len++;
average = average + (it.next() - average) / len;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.