首页 > 代码库 > 【算法】欧几里德算法--求最大公约数
【算法】欧几里德算法--求最大公约数
预备知识
因子(除数)
如果有整数 n,a,b 。a和b都不为0 ,且 有 n = a*b ,则说a(或者b,以下省略说明)为n的一个因子,或者说a能整除n。
特别的:任何非0整数都是0的因子,所以一般我们不会去求0的因子。
如:3 的因子有 1, -1 , 3 , -3 。然而我们一般只考虑正数因子,因为负数因子和正数因此没有本质上的区别,只是符号不同而已。
素数:素数(也加叫质数)的定义是,如果整数p的因子 只有 ±1 和 ±p,则它就是素数 。特别的:0 和1既不是素数,也不是合数。
合数一定能分解为 若干个 素数相乘的形式。如 27 = 3x3x3 ,155 = 5x31
模运算
a为正整数,且可以表示为: a = q*m+r ( r和q都是整数,且0<= r < q ), 则说: a mod q = r 。
例如: 7 mod 4 = 3 ,因为 7= 1*4 +3
我们并没有给出负数的模运算定义,因为它的定义不统一,也很少使用。但是要注意的是,在C/C++ 和 Java中,模运算的结果的符号和第一个操作数的符号相同。也就是说 a % b 的结果和 a 的符号相同。
模运算是很有作用的,例如,任何 正整数 mod m ,将会把他们映射到集合{0,1,2,...m-1}上。
欧几里德算法求最大公约数
将a ,b的公约数运算表示为函数gcd(a,b) 的返回值。a,b是不全为 0 的 非负数,且a >= b。
则 gcd(a,b) = gcd(b, a mod b) ,可以看见是一个递归调用,调用结束的条件是 : 第二个参数为 0,则返回的结果为 第一个参数。
也就是说:gcd(m,0) = m。
代码实现:
int gcd1(int a, int b) //使用递归 { assert(a >= b); if (b == 0) return a; else return gcd1(b, a%b); } int gcd2(int a, int b) //使用循环 { assert(a >= b); int r; while (b != 0) { r = a%b; a = b; b = r; } return a; }
【算法】欧几里德算法--求最大公约数