【问题标题】:Recursive GCD Logic Error递归 GCD 逻辑错误
【发布时间】:2014-01-20 23:58:20
【问题描述】:

据我所知,这其中的逻辑是有道理的。然而输出是不正确的,我似乎可以理解它。

#include <stdio.h>

int gcd(int, int);

int main()
{
    int n, m;

    printf("enter two numbers");
    scanf("%d%d", &n, &m);

    printf("The gcd of %d and %d is: %d \n", n, m, gcd(n,m));

    return 0;
}

int gcd(int x, int y)
{
    while(x!=y){
           if(x>y)
                    return (x-y,y);

            else
                    return(x,y-x);
    }
    return x;
}

【问题讨论】:

    标签: c recursion logic greatest-common-divisor


    【解决方案1】:

    这不是gcd递归 实现,该函数没有调用自身,而且它使用while 循环。真正的递归方法如下所示:

    int gcd(int x, int y) {
        if (y == 0)
            return x;
        else
            return gcd(y, x % y);
    }
    

    或者更短一点:

    int gcd(int x, int y) {
        return y == 0 ? x : gcd(y, x % y);
    }
    

    以上实现是基于欧几里得算法,详情请参考this

    【讨论】:

    • 是否可以不使用 ? b : c
    • 当然,?:if-else 的简写。请参阅我的更新答案。
    【解决方案2】:
    return (x-y,y);
    

    只会返回y。该代码可以编译,但可能不是您所期望的。

    非递归 Euclid GCD 算法如下所示:

    int gcd (int x, int y)
    {
        while (y != 0)
        {
            int r = x % y;
            x = y;
            y = r;
        }
        return x;
    }
    

    与递归版本相比:

    int gcd (int x, int y)
    {
        return y == 0 ? x : gcd (y, x%y);
    }
    

    在这些琐碎的例子中,递归方法使用的源代码较少,但效率低。

    xy 的副本加上返回地址在堆栈上传递,而线性版本仅使用中间变量 r 处理 x / y 的其余部分。

    即使某些编译器可能足够聪明,可以检测到不必要的递归并将其优化掉,但我认为了解递归编码的内在成本还是很有用的。

    【讨论】:

      猜你喜欢
      • 2016-05-14
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-12
      • 2012-08-02
      • 2016-02-21
      • 2019-03-05
      相关资源
      最近更新 更多