每个整数可以与整数本身的大小一样大(Java int-32位),因此将整数的总和存储在整数变量中不是一种选择。 我担心使用Java BigInts可能会严重影响性能。
现在我正在尝试分裂和征服,同时使用 long 存储总和。
有没有更好的解决方案?
答案 0 :(得分:6)
BigInt非常快。正如我经常说的那样,先做好,然后进行配置和优化。
答案 1 :(得分:6)
您可以使用长(64位)来保存总和。如果你超支,BigInteger就是你要走的路。
答案 2 :(得分:4)
long
数据类型怎么样?即使在32位机器上它也应该非常快。
答案 3 :(得分:2)
您可以使用浮点数,然后将结果转换回整数。这可能不是最佳的,但应该足够快(并且直截了当)
答案 4 :(得分:2)
如果你知道你必须提前平均的整数数量,你可以逐个进行划分
int [] a;
int average;
int remainder;
int alen = a.length;
for( int i = 0; i < alen; i++ ) {
int q = a[i] / alen; //calculate the quotient and the remainder for the current element
int r = a[i] % alen;
average += q; // add up the averages and the remainders
remainder += r;
if( remainder >= alen ) { //roll the average over if needed
remainder -= alen;
average++;
}
}
当然在实践中并不重要,因为数组中不能有超过2个 31 元素,这意味着您可以将总和存储在long
。< / p>
答案 5 :(得分:0)
除非您计算数十亿数字的平均值,否则使用BigInteger不会对性能产生太大影响。您应该尝试使用BigInteger对其进行编码,然后确定它是否足够快。
答案 6 :(得分:0)
将浮点与Kahan's summation一起使用。
答案 7 :(得分:0)
您可以长时间存储超过2亿的整数。问题是什么? 好吧,如果你需要更多的注意力。做一个包含多个longs的简单类(和long []会做),并在第1个顶部添加。每增加几十亿,就会有一个新的长。
最后(平均)将BigInteger中的长数相加并除以。代码几乎没有开销,一个额外的计数器和一个额外的检查(预测的分支)。
[希望我没有因为1而愚蠢;)
package t1;
import java.math.BigInteger;
import java.util.Arrays;
public class Avg {
long sum;
long[] totals = new long[0];
int counter;
public void add(int v){
if (counter++==Integer.MAX_VALUE){
counter = 0;
int len =totals.length;
totals = Arrays.copyOf(totals, len+1);
totals[len]=sum;
sum = 0;
}
sum+=v;
}
public int avg(){
long count = this.counter;
count+=totals.length*(long)Integer.MAX_VALUE;
BigInteger sum = BigInteger.valueOf(this.sum);
for (long subSum : totals)
sum=sum.add(BigInteger.valueOf(subSum));
return sum.divide(BigInteger.valueOf(count)).intValue();//tweak if you need be
}
}