这一次我们同时使用递归与循环解决问题。
求最大公约数,最经典的方法莫过于辗转相除法,也叫欧几里得法。
其计算原理依赖于下面的递推式:
gcd(m, n) = gcd(n, m mod n)
整数m、n的最大公约数等于n和m除以n的余数的最大公约数。
开始我们的递归分析:
1.简单情况, m % n == 0, 此时n就是m和n的最大公约数,直接返回。
2.一般情况,m % n = r, r != 0, 此时n取代m的位置,r取代n的位置,开始新的自身调用。
代码:
#include <stdio.h>
int rgcd(int m, int n)
{
if (m % n == 0)
return n;
return rgcd(n, m % n);
}
int cgcd(int m, int n)
{
int r = m % n;
while (r)
{
m = n;
n = r;
r = m % n;
}
return n;
}
int main(void)
{
printf("%d\n", rgcd(24, 42));
printf("%d\n", cgcd(32, 24));
return 0;
}
我们可以看到,递归写出的代码相当简洁优雅,但是需要我们的抽象能力与整体思考能力,不然就容易写出死递归或者往错误的方向递归。