(Unfinished)2017暑假北京学习 day 2

一、概念引入

  GCD,全名Greatest common divisor(最大公因数)。

  我们以gcd(a,b)或(a,b)表示a与b的最大公因数。

 

  LCM,全名Least Common Multiple(最小公倍数),

  我们以lcm(a,b)或[a,b]表示a与b的最小公倍数。

 

二、求最大公约数-欧几里得算法

  用途:

    求解gcd(a,b)

  核心公式:

    gcd(a,b) = gcd(b,a mod b)  (其中a mod b > 0)

    或者gcd(a,b) = gcd(c,d) ( 其中a<b,c=max(b,a-b),d=min(b,a-b) )

  算法思路:

    (保证a>b)

    当a是b的倍数时,a,b最大公约数为b;

    *PS:此时,a mod b = 0,即gcd(a,b) = gcd(b,a mod b) = gcd(b,0) = b,可用于边界判断;

    当a不是b的倍数时,运用核心公式,直到a'是b'的倍数。

    *PS:因为b' = (a mod b) < b,所以a,b两个值在不断调用gcd的过程中将逐渐递减,直至b=0;

  代码:

 1 int gcd(int a,int b)
 2 {
 3     if(b==0)
 4         return a;
 5     else 
 6     {
 7         if(a<b)
 8         {
 9             a=a+b;//a'=a+b
10             b=a-b;//b = a'-b = a+b-b = a
11             a=a-b;//a'' = a'-b' = a+b-a = b
12         }
13         return gcd(b,a%b);     
14     }
15 }

 

  *核心公式证法1.

    第一步(证明d是a,b公约数时,d也是b,a mod b的公约数【反应正向进行】):

    ——a可以表示成a = kb + r(a,b,k,r皆为正整数,且r<b),

    ——则r = a mod b

    ——假设d是a,b的一个公约数,记作 d|a, d|b,即a和b都可以被d整除。

    ——而r = a - kb,两边同时除以d,r/d = a/d - kb/d = m,由等式右边(a和b都可以被d整除)可知m为整数,

    ——因此d|r,已知r = a mod b

    ——综上,d|b 且 d|(a mod b)

    ——因此d也是b,a mod b的公约数

 

    第二步(证明d是b,a mod b的公约数时,d也是a,b公约数【反应逆向进行】):

    ——假设d是b,a mod b的公约数, 则d|b,d|(a-k*b),k是一个整数,

    ——进而d|a.

    ——因此d也是a,b的公约数

    ——因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,

 

  综上,欧几里得算法核心公式得证。

 

三、求最小公倍数 - 大数翻倍法

  公式法:

    非常简单,∵gcd(a,b) × lcm(a,b) = a × b,

    ∴lcm(a,b) = a × b ÷ gcd(a,b),其中gcd(a,b)可以用欧几里得算法求解。

  大数翻倍法:

    思路也很简单,

    ∵lcm(a,b),同时是a与b的倍数,所以取a,b较大数不断翻倍,直到结果能够整除较小数即可。

 1 int lcm(int a,int b)
 2 {
 3     int i;
 4     if(a<b)
 5     {
 6         i=a; a=b; b=i;
 7     }
 8     
 9     i=1;
10     while( (a*i) % b != 0 )
11         i++;
12     return a*i;
13 }

四、求最大公约数-Stein算法

    这个算法是针对位数很多的大整数(接近10^10^4)所设计的。未完待续。。。

原文地址:https://www.cnblogs.com/CXSheng/p/7521967.html