2 回答

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊
看起來(lái)您正在添加 width 的滑動(dòng)窗口的產(chǎn)品c。如果您想提高性能,請(qǐng)擺脫遞歸并避免重新計(jì)算整個(gè)產(chǎn)品。使用在上一步中計(jì)算的乘積:將其乘以進(jìn)入窗口的數(shù)字并除以退出窗口的數(shù)字。除法速度較慢,但它會(huì)為更大的 值帶來(lái)回報(bào)c。
最后,雖然我會(huì)保留你的方法簽名,但你真的只需要BigInteger作為回報(bào)。
BigInteger getSum(BigInteger n, BigInteger c) {
BigInteger p = BigInteger.ONE, sum = BigInteger.ZERO;
for (BigInteger x = BigInteger.ONE; x.compareTo(n) < 0; x = x.add(BigInteger.ONE)) {
p = p.multiply(x);
if (x.compareTo(c) > 0) {
p = p.divide(x.subtract(c));
}
sum = sum.add(p);
}
return sum;
}
如果您想進(jìn)一步加快速度,可以使用一些數(shù)學(xué)知識(shí)來(lái)避免在每一步都進(jìn)行除法。您的總和可以分解為s1 = sum[1,c) x!和s2 = sum[c,n) x!/(x-c)!。第二個(gè)總和等于n!/(n-c-1)!/(c+1)(來(lái)自hockey stick identity)。下面的方法不處理 c >=n 的簡(jiǎn)單情況。我會(huì)把它留給你。
private static BigInteger fasterSum(BigInteger n, BigInteger c) {
assert c.compareTo(n) < 0;
BigInteger sum = ZERO, p = ONE;
for (BigInteger x = ONE; x.compareTo(c) < 0; x = x.add(ONE)) {
p = p.multiply(x);
sum = sum.add(p);
}
// sum[c,n) x!/(x-c)! = n!/(n-c-1)!/(c+1)
p = ONE;
for (BigInteger x = n.subtract(c); x.compareTo(n) <= 0; x = x.add(ONE)) {
p = p.multiply(x);
}
sum = sum.add(p.divide(c.add(ONE)));
return sum;
}

TA貢獻(xiàn)1880條經(jīng)驗(yàn) 獲得超4個(gè)贊
所以我假設(shè)你想添加一個(gè)列表BigInteger:
你可以通過(guò)使用減少操作來(lái)做到這一點(diǎn)(https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html)
List<BigInteger> list = new ArrayList<>();
list.add(BigInteger.valueOf(5));
list.add(BigInteger.valueOf(1));
list.add(BigInteger.valueOf(3));
list.add(BigInteger.valueOf(10));
list.add(BigInteger.valueOf(2));
BigInteger sum = list.stream().reduce((x, y) -> x.add(y)).get();
System.out.println(sum);
這將計(jì)算總和,相當(dāng)于:
BigInteger sum = list.stream().reduce(BigInteger::add).get();
您還可以自己編寫(xiě)一個(gè)Collector可重用的并將 reduce 操作提取到那里:
public static Collector<BigInteger, ?, BigInteger> calculateSum() {
return Collectors.reducing(BigInteger.ZERO, BigInteger::add);
}
然后做:
BigInteger sum = list.stream().collect(calculateSum());
添加回答
舉報(bào)