【算法】欧几里德算法--求最大公约数

预备知识

 

因子(除数)

如果有整数 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;
}

 

posted @ 2017-04-09 13:52  lulipro  阅读(1611)  评论(0编辑  收藏  举报