int gcd(int a, int b){ return b == 0 ? a : gcd(b, a % b); }
定理:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。
(最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。)
其实总的来说,这个递归的主要思想就是:
计算公式:
gcd(a,b) = gcd(b,a mod b)
过程:
假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:
1997 / 615 = 3 (余 152)
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。
int gcd(int a, int b)
{ return b == 0 ? a : gcd(b, a % b); }
1.其实写这个函数代码的时候最好的理解就是,把这个代码当做已经执行过很多次或者最后一次来写(递归函数),就把a看成除数,b看成余数,因此b如果等于0就返回a的值;当然第一次用gcd时是被除数与除数,还不是可以看成一个除数与一个余数,因为它们要进行的是同样的操作;
2.第一次引入a,b是被除数与除数;
之后递归gcd()函数是为了在余数(第二个数)为0的时候返回除数(第一个数);
括号内第一个数表示除数,第二个表示除完后的余数;
如果此轮的余数不为0,此余数会是下一轮的除数所以上面gcd的b是第二个数,而下面的gcd的b在第一个数的位置;
3.第一次引入a和b的时候大小没有要求,a大于b,a小于b都行;
因为如果一开始a小于b(被除数小于除数),没有关系,因为不看商。这时余数(a)会是原来的被除数(a),而在下一轮中,原来除数(b)变成了被除数(b),而原来的被除数(a)作为上一轮的余数(a),变成了这一轮的除数(a),正好两个数的关系转换了,之后的步骤都是对的了。
ps:递归好难理解(哭),解释的很多是因为我怕什么时候我又忘记这个递归函数为什么要这样写了~