递归困境

时间:2013-01-08 20:54:02

标签: java

我正在尝试创建代码来查找三个用户输入数字的GCD。我的目标是用输入的数字调用方法,除以q,初始化为1,仅当余数为零时记录q,然后确定它是否大于或等于最小数,如果不是,则增加q和召回方法,但如果是我想打印出最大的最后记录q,我做错了什么?我不断收到堆栈溢出错误。

public static int recursiveMethod (int x, int y, int z, int q)
{
    int largestVar; 
    int xRes = x % q;
    int yRes = y % q;
    int zRes = z % q;
    if (xRes==0 && yRes ==0 && zRes==0) {
                largestVar = q;
                if (q >= x && q >= y && q >= z)
                {
                    return largestVar;
                }
    }
    else { 
           q++;
    }
   return recursiveMethod(x, y, z, q);

4 个答案:

答案 0 :(得分:4)

我注意到的一个错误,你的if条件错了:

if (q >= x && q >= y && q >= z)

这3个数字的GCD小于或等于每个数字,因此将其更改为:

if (x >= q && y >= q && z >= q)

如果你像这样迭代地测试数字,你应该从一定的数字和倒计时开始,这样你就可以保证满足条件的数字是实际的GCD。并且某个起始编号必须是最少3个数字。 您的方法的完整工作版本在这里:

public static int recursiveMethod(int x, int y, int z, int q) 
{
    int largestVar;
    int xRes = x % q;
    int yRes = y % q;
    int zRes = z % q;
    if (xRes == 0 && yRes == 0 && zRes == 0) {
        largestVar = q;
        if (x >= q && y >= q && z >= q) {
            return largestVar;
        }
    } else {
        q--;
    }
    return recursiveMethod(x, y, z, q);
}

示例电话:

int x = recursiveMethod(30, 60, 45, 30); // x = 15 after this execution.

答案 1 :(得分:2)

不要忘记gcd(x, y, z) = gcd(gcd(x, y), z).所以,如果你想要一个更简单的算法,你可以用两个数字实现gcd,然后为3个数字调用该方法。

public static int GCD(int x, int y) {
   if (y == 0) return x;
   return GCD(x, x % y);
}

然后是三个数字:

public static int GCDfor3 (int x, int y, int z) {
    return GCD(GCD(x, y), z)
}

答案 2 :(得分:1)

你的第一个案例将是1,此时,xRes==0 && yRes ==0 && zRes==0肯定是真的,并且你将maximumVar设置为1.然后,因为1可能小于传入的变量,它继续,不增加q在else块中,再次调用recursiveMethod q = 1!这个过程重演了。

public static int recursiveMethod (int x, int y, int z, int q, int largestVar)
{
    int xRes = x % q;
    int yRes = y % q;
    int zRes = z % q;
    if (xRes==0 && yRes ==0 && zRes==0) {
    //A common denominator found!
                largestVar = q;
    }
    //regardless whether a denominator was found, check for the termination condition
    //Or works here, by the way, since we only need to know when q is greater than one of them.
    if (q >= x || q >= y || q >= z) {
        return largestVar;
    }
    //if we don't terminate, increment q and recurse. 
    q++;
    return recursiveMethod(x, y, z, q, largestVar);
}

修改为正确处理largestVar。没注意那一点。作为本地作用域,maximumVar的值不会通过递归调用来维护,因此它也必须传递给recursiveMethod调用(要么被调用,要么被声明为类作用域变量,或者某些类变量)。适当的起始值为0。

答案 3 :(得分:0)

如果每次将Q递增1,使用合适的数字,您将始终没有堆栈。我会为每对数字使用欧几里德算法,然后从那里开始。我的意思是,如果它在a,b,c之间是常见的,它必须是a和b或a和c或c和b之间的共同因素,对吧?

https://math.stackexchange.com/questions/85830/how-to-use-the-extended-euclidean-algorithm-manually