有连续的整数流,并且必须在任何给定实例中仅使用内存来计算平均值。
答案 0 :(得分:2)
具有纳秒级的分辨率,几天内您的商品数也会溢出。
但是,您可以-而不是保留总和-保留旧的平均值,并在新物品到达时重新称重。
private static void average(int... amount) {
double average = (double) amount[0];
for (double i = 1; i < amount.length; i++) {
System.out.printf("average: %d%n", (int) average);
double newWeight = (i + 1d) / i;
double newAverage = average / newWeight;
double thisAverage = (amount[(int)i]) / (i+1d);
average = newAverage + thisAverage;
}
System.out.printf("average: %d%n", (int) average);
}
关于它为什么起作用,假设您正在查看值
3,2,5
第一个值的平均值为
3/1 = 3
(值的数量为“ 1”)。
现在,两个人到了。这意味着我们想要(3 + 2)/ 2或(3/1)/ 2 +(2/2),因此我们将之前的平均值“ 3”除以(1 + 2)/ 2。现在是新的平均值
3/2 + 2/2 = 2.5
现在5点到了。现在我们要
(3 + 2 + 5)/ 3 =(3 + 2)/ 3 + 5/3
或-因为我们(3 + 2)中不再有3和2-
=(3 + 2)/ 2 * 2/3
(3 + 2)/ 2是旧的平均值,2是旧的计数,3是新的计数。
答案 1 :(得分:0)
Java 8平台提供了一个IntStream,使您可以简单地调用average()。
int[] allInts = { 1, 2, 3, ..., n };
OptionalDouble average = IntStream.of(allInts).average();
我不知道您的整数流是什么样子,因此,如果您更新问题,我可以更新我的答案。
答案 2 :(得分:0)
您可以使用BigDecimal
来保留总和和平均值;不会溢出。
public void test(int[] values) {
BigDecimal sum = BigDecimal.ZERO;
for (int count = 0; count < values.length; count++) {
sum = sum.add(new BigDecimal(values[count]));
System.out.printf("%s/%d = %s%n", sum, (count+1), sum.divide(new BigDecimal(count+1)));
}
}
但是我认为这不值得麻烦。在大多数情况下,仅使用long
代替int
就足够了。