我有这种奇怪的错误。
我正在尝试使用BigInteger类实现基本的欧几里德算法,如图所示。当我运行它时,它会抛出StackoverFlowError,而如果我调试它,它会正确运行并给我正确的答案。
我认真地不了解调试和正常运行期间的差异。
static BigInteger gcd(BigInteger a, BigInteger b) {
if (a.equals(BigInteger.ZERO)) {
return b;
} else if (b.equals(BigInteger.ZERO)) {
return a;
}
BigInteger max = a.max(b);
BigInteger min = a.min(b);
return gcd(max.subtract(min), min);
}
答案 0 :(得分:0)
如果用mod操作替换重复减法,算法将需要更少的调用。检查如果max非常大且min非常小,会发生什么。
答案 1 :(得分:0)
这不是GCD的欧几里德算法。正确的GCD算法可以很容易地说明为递归过程,因为迭代次数实际上很小。但是这种错误实现的算法可以运行数百万次迭代,例如如果'a'是1,000,000且'b'是1,则会产生一百万次递归调用。
(但是,调用是一个尾递归调用,所以一个好的Java实现实际上会优化掉堆栈帧。但是,这似乎不会发生在这里。虽然由于一些未知的原因,调试器版本可以实现尾调用优化,虽然听起来很奇怪。)
在实际算法中,递归步骤是(a%b,b)而不是(a - b,b)。 Google为“euclid GCD算法”。