最近做题目发现一些题目需要求数的最大公约数和最小公倍数,想想最大公约数和最小公倍数平时做数学的时候感觉不是很难,但是突然要编程来实现,却一下子不知所措了,后来看了下别人写的,发现其实也不算特别难。最小公倍数其实只要一个公式,即整数A和整数B的最小公倍数为A*B/gcd(A,B)(gcd(A,B)为A和B的最大公约数),可见A和B的最小公倍数就为A和B的乘积再除以它俩的最大公约数,也就是说最终还是要求最大公约数,所以以下主要讨论最大公约数算法。最大公约数的算法原来还分为两种,一种是用非递归的算法,一种是递归的算法。递归的算法在二叉树里面是很常见的,以及斐波那契数列的实现上,对于递归算法的优点就是代码可以极其简短,缺点则是需要不断调用函数,效率不用直接用循环。
无论是通过递归还是非递归的方法,一下的代码都是基于一种求两个数最大公约数的算法——辗转相除法。辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的相除余数的最大公约数。例如,252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);因为252 / 105 = 2余42,所以105和42的最大公约数也是21。在这个过程中,较大的数缩小了,所以继续进行同样的计算可以不断缩小这两个数直至余数变为零。这时的除数就是所求的两个数的最大公约数。
以下是求最大公约数递归算法
//最大公约数(递归算法)
int gcd( int x , int y){
if( y == 0 )
return x;
else
return gcd(y,x%y);
}
从上面可以看出,递归算法极其简短,而下面的非递归算法相对则长一点。
//最大公约数(非递归算法)
int gcd( int x , int y){
int max,min,temp;
max = x > y ? x : y ;
min = x < y ? x : y ;
while( max % min ){
temp = max % min;
max = min;
min = temp;
}
return min;
}
//最小公倍数
int lcm( int x , int y ){
return x*y/gcd(x,y);
}