0

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;
    }
}
}
4

3 回答 3

6

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

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

把它写成一个C格式,就是这样。

于 2013-02-15T15:07:31.163 回答
2
int gcd(int a, int b) { 
   if (b == 0) 
   then return a
   else return gcd(b, a % b);
}

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

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

于 2013-02-15T15:13:09.820 回答
1

通常,人们努力消除递归,而不是引入它。

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

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 的最佳算法,但它采用您提供的函数并根据要求将其转换为递归。

于 2013-02-15T15:23:37.313 回答