的StackOverflowError

时间:2012-05-18 11:06:39

标签: java algorithm stack-overflow

我有这种奇怪的错误。

我正在尝试使用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);
      }

2 个答案:

答案 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算法”。