【发布时间】:2021-06-28 05:21:22
【问题描述】:
我的任务是确定斐波那契数列中从 A 到 B 的数字之和是否可以被数字 D 整除。
我使用快速加倍算法在数列中找到需要的数,并使用公式:
Fa + ... + Fb sub> = Fb+2 - 1 - (Fa+1 - 1) - 确定级数之和,但这还不够。为了测试,我取了一个从 A = 10,000,000 到 B = 20,000,000 的序列,数字 D = 987654,程序在 3.3 秒内执行,这已经很多了。有没有办法优化我的代码?
class Solution {
private static Map<BigDecimal, BigDecimal> previousValuesHolder;
static {
previousValuesHolder = new HashMap<>();
previousValuesHolder.put(BigDecimal.ZERO, BigDecimal.ZERO);
previousValuesHolder.put(BigDecimal.ONE, BigDecimal.ONE);
}
private static BigInteger totalSum;
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
int nb = in.nextInt();
for (int i = 0; i < nb; i++) {
int a = in.nextInt();
int b = in.nextInt();
int d = in.nextInt();
totalSum = calculateTotalSum(a, b);
System.out.println(checkSum(totalSum, a, b, d));
}
}
private static BigInteger calculateTotalSum(int start, int finish) {
BigInteger res1 = fibDoubleFast(finish + 2).subtract(BigInteger.valueOf(1));
BigInteger res2 = fibDoubleFast(start + 1).subtract(BigInteger.valueOf(1));
return res1.subtract(res2);
}
private static String checkSum(BigInteger sum, int start, int finish, int d) {
BigInteger result = sum.remainder(BigInteger.valueOf(d));
return result.longValue() > 0
? String.format("F_%s + ... + F_%s is NOT divisible by %s", start, finish, d)
: String.format("F_%s + ... + F_%s is divisible by %s", start, finish, d);
}
private static BigInteger fibDoubleFast(int n) {
BigInteger a = BigInteger.ZERO;
BigInteger b = BigInteger.ONE;
int m = 0;
for (int bit = Integer.highestOneBit(n); bit != 0; bit >>>= 1) {
BigInteger d = multiply(a, b.shiftLeft(1).subtract(a));
BigInteger e = multiply(a, a).add(multiply(b, b));
a = d;
b = e;
m *= 2;
if ((n & bit) != 0) {
BigInteger c = a.add(b);
a = b;
b = c;
m++;
}
}
return a;
}
private static BigInteger multiply(BigInteger x, BigInteger y) {
return x.multiply(y);
}
}
【问题讨论】:
-
codereview.stackexchange.com 可能是这个问题的正确位置。
-
一旦你有一个可以被 D 整除的数字,不是更好吗?
-
@JoakimDanielson 这没有意义,即使我只输入了 1 行,测试仍然没有及时通过
-
你误解了我的意思,我的意思是你应该重写 calculateTotalSum 以便它在你找到一个数字后立即返回。无论如何,这更像是一个调查建议,而不是解决方案。
-
1.当您返回
res1.subtract(res2)时,为res1和res2执行.subtract(BigInteger.valueOf(1))毫无意义。(x - 1) - (y - 1)与x - y相同。 2. 没有理由将totalSum声明为static变量。 3. 不要将String.format用于可以表示为纯字符串连接的内容。 4.删除未使用的东西,previousValuesHolder没有任何用途,m永远不会使用。 5. 避免冗余计算的一种简单方法是向multiply添加缓存。
标签: java performance optimization fibonacci