2014-04-23 60 views
3

我在採訪中被問到了這個問題。 有人問我計算數字X1,X2,X3,...的平均XNJava中整數的溢出

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個變量進入某種列表?任何人都有線索?

+0

相關的問題: http://stackoverflow.com/questions/1657834/how-can-i-check-if - 在數字中乘以兩個數字將導致溢出 http://stackoverflow.com/questions/12226634/how-to-prevent-integer-overflow-in-java-code –

+0

你寫了「計算總和「,你的意思是平均值,對嗎? – icza

回答

3

我不知道如何使用堆棧,但在代數的幫助下,我們可以使用舊的平均值推導出新平均值的公式。

假設您已經平均使用n - 1項,並且您在oldAvg中擁有該平均值。

oldAvg =(X 1 + X + .. + X N - 1)/(N - 1)

新平均將由newAvg表示:

newAvg =(X 1 + X + .. + X N - 1 + X ñ)/ N

通過一些代數操作,我們可以使用舊的平均平均物品數量和下一個物品來表示新的平均值。

newAvg =(X 1 + X + .. + X N - 1)/ N + X Ñ/N

=((N - 1)/(N - 1))*(X 1 + X + .. + X N - 1)/ N + X ñ/N

= oldAvg/N *(N - 1)+ x n/n

這樣可以避免溢出除以n,然後再乘以n - 1。然後,你所要做的就是在下一個項目中加上x n,除以n

第一個循環會將平均值確定爲等於第一個元素,但每個後續循環將使用上面的公式來推導新的平均值。

n++; 
newAvg = oldAvg/n * (n - 1) + it.next()/n; 
2

他可能指的是你不需要所有的術語來計算平均值,你可以跟蹤一個moving average。這可以與目前被認爲與術語總和相關的術語的數量一起使用。

由於總數可能太大而無法長期存儲,因此您希望使用類似BigInteger的東西來保存總數。

+0

您能詳細解釋一下嗎?因爲他確實提到了BigDecimal,然後繼續在移動平均中討論他的下一個問題。 – user1529412

2

如果您簡化rgettman的製劑還你會得到如下:

len++; 
average = average + (it.next() - average)/len;