码迷,mamicode.com
首页 > 编程语言 > 详细

day 2 - 4 最大公因数 与 (扩展)欧几里得算法

时间:2017-09-16 18:49:06      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:过程   int   引用传递   code   greatest   www   return   targe   相关   

一、概念引入

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

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

 

二、欧几里得算法(又名辗转相除法)

  用途:

    求解gcd(a,b)

  核心公式:

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

  算法思路:

    (保证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;

  代码:

int gcd(int a,int b)
{
    if(b==0)
        return a;
    else 
    {
        if(a<b)
        {
            a=a+b;//a‘=a+b
            b=a-b;//b = a‘-b = a+b-b = a
            a=a-b;//a‘‘ = a‘-b‘ = a+b-a = b
        }
        return gcd(b,a%b);     
    }
}

  *核心公式证法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)的公约数是一样的,其最大公约数也必然相等,

 

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

 

三、扩展欧几里得算法

  用途:

    扩展欧几里得算法 是用来在已知a, b求解一组x,y

    使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据数论中的相关定理)。

    常用在求解模线性方程及方程组中。

    编程时 exGcd 更多用于求解“中国剩余定理”相关知识。比如“比如n除以5余2,除以13余3,那么n最小是多少,所有的n满足什么条件?”

  时间复杂度:

    用扩展欧几里得算法求 n 个不超过 m 的正整数的最大公约数的复杂度是 O(n+logm)。

  代码:

/*已知a,b(a>b),求解x,y,满足ax+by=gcd(a,b),并同时返回gcd(a,b)*/
int exGcd(int a,int b,int &x,int &y)//x,y使用了引用传递的方式 
{
    if(b==0)
    {
        x=1;
        y=0; 
    /*
    当a%b==0时,显然gcd(a,b)=b,
    所以b = gcd(a,b) = gcd(b,a%b) = gcd(b,0)
    此时显然 b*1+0*0 = gcd(b,0) = gcd(a,b)
    故 x=1,y=0
    */
    }
    else
    {
        //g=gcd(a,b)
        int g = exGcd(b,a%b,x,y);
        int t = x;
        x = y;
        y = t - a/b * y;
        return g;
        /*
        求解 x,y的方法的理解:
      设 a>b。
      1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
      2,a>b>0 时
      设 ax1+ by1= gcd(a,b);
      bx2+ (a mod b)y2= gcd(b,a mod b);
      根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
      则:ax1+ by1= bx2+ (a mod b)y2;
      即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
      也就是ax1+ by1 == ay2+ b(x2- [a / b] *y2);
      根据恒等定理得:
    
        x1=y2;
        y1=x2- [a / b] *y2;
    
      这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
      上面的思想是以递归定义的,因为 gcd 不断的递归求解,一定会有个时候 b=0,
所以递归可以结束。
*/ } }

 

四、扩展欧几里德算法的扩展~(--n--*)~

  用途:

    扩展欧几里德算法不但能计算(a,b)的最大公约数,而且能计算a模b及b模a的乘法逆元(尽管不是最佳算法),即求解“中国剩余定理”。

  /*鄙人才疏学浅,这一块还没有认真学习,以后再补充吧*/

day 2 - 4 最大公因数 与 (扩展)欧几里得算法

标签:过程   int   引用传递   code   greatest   www   return   targe   相关   

原文地址:http://www.cnblogs.com/MicoTimlesCheng/p/7521967.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!