【问题标题】:Recursion in C. Making a non-recursive function a recursive oneC中的递归。使非递归函数成为递归函数
【发布时间】:2013-02-15 15:04:05
【问题描述】:

gcd 应该是一个递归函数。它应该返回无效。它应该取两个正整数并将 GCD 放在第三个参数中。

这是我的编码 gcd 函数。但是,我意识到它不是递归函数。我将如何更改此代码使其成为递归函数?

void gcd(int *x, int *y) {
int i;
getValuesForGCD(x, y);
for (i = *x; i >= 1; i--)
{
    if (*x % i == 0 && *y % i == 0)
    {
        printf("The GCD of %d and %d is %d", *x, *y, i); 
        break;
    }
}
}

【问题讨论】:

  • 将非递归函数转换为递归函数听起来不太实用。通常人们试图消除递归,而不是引入它。你为什么要引入递归?
  • 为什么是指针?附带说明一下,修改上面的算法,例如 i 从 min(x,y) 开始。
  • @RaymondChen 有些东西以递归方式更具可读性和自然性,gcd 就是其中之一。虽然,在这种情况下,它可能是一个硬件......
  • 我不知道这里发生了什么,但请停止破坏您的问题。我暂时锁定它。

标签: c recursion


【解决方案1】:

GCD 自然地被定义为一个循环公式。它直接转化为递归函数:

gcd(a, 0) = a
gcd(a, b) = gcd(b, a % b)

C 格式写就行了。

【讨论】:

    【解决方案2】:
    int gcd(int a, int b) { 
       if (b == 0) 
       then return a
       else return gcd(b, a % b);
    }
    

    您应该注意到 a 和 b 必须是非负数。

    好消息是,这是一个尾递归,因此它的运行速度与非递归方法一样快。

    【讨论】:

    • 可以跑得一样快。仅当编译器执行 TCO 时才会发生这种情况。
    • @cHao 经常,如果编译器不支持TCO,它通常也不支持递归(这意味着你不能做递归方法)。
    • BS。对递归的支持只需要一个堆栈来传递参数和返回地址,这通常内置在 CPU 中。过去 30 多年制造的几乎所有编译器都支持它,而且其中很大一部分没有 TCO。
    【解决方案3】:

    通常,人们会移除递归,而不是引入它。

    如果您希望将迭代算法文字转换为递归,则如下所示:

    void gcdrecursive(int *x, int *y, int i)
    {
        if (i >= 1) {
            if (*x % i == 0 && *y % i == 0) {
                printf("The GCD of %d and %d is %d", *x, *y, i); 
            } else {
                gcdrecursive(x, y, i - 1);
            }
        }
    }
    
    void gcd(int *x, int *y) {
        getValuesForGCD(x, y);
        gcdrecursive(x, y, *x);
    }
    

    要将迭代解决方案转换为递归解决方案,请将每个循环转换为执行循环的一次迭代的递归函数,然后递归调用自身以进行下一次迭代。打破循环对应于停止递归。在您的示例中,循环中断有两个原因:找到 GCD 或 i 达到零。

    请注意,这不是 gcd 的最佳算法,但它采用您提供的函数并根据要求将其转换为递归。

    【讨论】:

    • @QweRty 不要忘记在你的作业中感谢我。否则就是抄袭。
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    相关资源
    最近更新 更多