欧几里得算法&&扩展欧几里得算法<数论>

来源:互联网 发布:cctv2郑州淘宝诈骗 编辑:程序博客网 时间:2024/06/05 11:37

欧几里得算法

  • 欧几里得算法用于求两个数的最大公约数,也叫辗转相除法
  • 证明:若 a=k*b+r
    则r=a%b 且r=a-k*b
    所以若存在 g是a,b的最大公约数( g|a && g|b )
    那么一定有 g|(a-k*b) 则一定 g|(a%b)
    所以a和b的最大公约数就是b和a%b的最大公约数
  • 终止条件:a%b为0是,返回此时的a,也就是a%b中的b
  • 举个例子模拟一下:
    a=20,b=15
    20和15的最大公约数就是15和5的最大公约数
    15和5的最大公约数就是5和0的最大公约数 即为5
int gcd(int a,int b){    if(!b) return a;    return gcd(b,a%b);}

扩展欧几里得算法

  • 欧几里得算法求的是两个数的最大公约数,扩展欧几里得算法可以求出
    a*x+b*y=gcd(a,b) 的x,y 通解,即求出最大公约数的同时可以求出一组x和y,使得原式成立
    先看一下写法(有“//”的代码很重要)
int exgcd(int a,int b,int &x,int &y){    if(!b){        x=1;y=0;//        return a;    }    int ans=exgcd(b,a%b,x,y);    int xx=x;//    x=y;//    y=(xx-a/b*y);//以上这三行是扩欧的精髓    return ans;}
  • 终止条件:这和欧几里得算法是一样的。不同的是,除了要返回gcd外,还要给x和y赋值。因为此时b为0,所以a*1+b*0==gcd,所以x=1,y=0;
  • 递归过程:比欧几里得算法多出的步骤是给x,y一步步赋值,直到得到答案。
  • 正确性证明:
    设此时函数为ecgcd(a,b,x,y)
    则下一次递归的函数为exgcd(b,a%b,x,y)
    假设我们已经得到一组x和y(终止时得到),那么返回上一个函数时,x,y应该怎样变化?
    将得到的x和y带入方程,有 b*x+a%b*y=gcd
    又因为 a%b=a-a/b*b
    所以得到 b*x+(a-a/b*b)*y=gcd
    进一步化简 a*y+b*(x-a/b*y)=gcd
    又因为 a*x+b*y=gcd
    所以可以得到两个函数之间x,y的关系
    原式得证