这个gcd的实现是否正确

时间:2013-07-11 19:58:10

标签: java greatest-common-divisor

public static int divisor(int m, int n) {
    if (m == 0 || n == 0) {
        return m+n;
    } else {
        return divisor(n, m%n);
    }
}

在amazon.interviewstreet.com中,它给出了一些输入的错误答案(我不知道哪些输入不会显示它们用于测试用例的输入)

此外,为什么这个实现不断给我stackoverflow(再次不知道哪些输入)

public static int divisor(int m, int n) {
    if(m == 0 || n == 0) {
        return m+n;
    } else if (m > n) {
        return divisor(n, m%n);
    } else {
        return divisor(m, n%m);
    }
}

请让我知道我错过了什么。我是编程新手,我还是初学者。

6 个答案:

答案 0 :(得分:1)

我认为

return(m, n%m);

应该是

return divisor(m, n%m);

答案 1 :(得分:1)

可能无效处理nm的负值? 阅读例如这个:Best way to make Java's modulus behave like it should with negative numbers?

答案 2 :(得分:1)

第二部分是什么

return(m,n%m);

此代码是否已编译?

使用:

public static int divisor(int m, int n) {
if(m == 0 || n == 0)
    return m+n;
else if(m>n)
    return divisor(n, m%n);
else
    return divisor(m, n%m);}

答案 3 :(得分:1)

首先,

return(m, n%m) 

肯定不会编译,我想它本来是

return divisor(m, n%m);

其次,我猜第二个片段中的错误是处理负数。 因为A和B与-A和-B具有相同的GCD,所以我会添加

m = Math.abs(m);
n = Math.abs(n);

到方法的开头

答案 4 :(得分:1)

我认为第一个是编程竞赛的代码。如果是这样,请注意您的数据类型。可能'int'不足以容纳输入。试试'长'而不是。 (只有在算法正确的情况下,这才有效。)

答案 5 :(得分:1)

第二部分:

  

为什么这个实现不断给我stackoverflow(再次不知道哪些输入)?

试试这个输入集:

5 3 1 16 5 10

它将为您提供stackoverflow错误。对于您在pastebin中的给定代码。

为什么?

如果输入为“1”,则会出现此问题。

编辑您的代码部分,如下所示,并查看输入的输出(1 1)。

public static int divisor(int m, int n) {
    System.out.println("### "+m+" "+n);
    if (m == 0 || n == 0) {
        return m + n;
    } else if (m > n) {
        return divisor(n, m % n);
    } else {
        return divisor(m, n % m);
    }
}

在某些方面,out put会是这样的:

.
.
### 1 1134903170
### 1 0
### 1 1836311903
### 1 0
### 1 -1323752223
### -1323752223 1
### -1323752223 1
### -1323752223 1
.
.

因为在你的代码中函数调用如下所示。

   public static int divFib(int num) {
    int i = 1, j = 2, temp;

    while (divisor(num, j) == 1) {
        temp = j;
        j = j + i;
        i = temp;
    }
    return j;
   }
divisor(num,j)将被调用为divisor(1,2),然后部分将执行

else {
        return divisor(m, n % m);
    }

调用将像divisor(1,0),因为n%m = 2%1 = 0

然后'1'将返回为(m + n = 1)。

然后while(divisor(num,j)== 1){}将再次执行,'j'将会增加。但'num'是'1'。同样的事情一次又一次地发生。结果'j'是一个巨大的数字,最终会分配一个负数。 (我想你知道它为什么会发生)。

事情是这永远不会停止。因此,由于大量的函数调用,堆栈将溢出。

我认为这是一个非常明确的解释,如果您有任何疑问,请询问。 (对不起,我错误地在这里发布了答案。)