精华内容
下载资源
问答
  • GCD 使用计算最大公约数。 例子 var gcd = require ( 'gcd' ) ; var n = gcd ( 121 , 44 ) ; console .... 使用欧几里德算法返回整数a和b最大公约数。 安装 用做: npm install gcd 执照 麻省理工学院
  • 课程的随堂作业,C语言的,用dev就能运行,萌新代码,勿喷,仅仅帮助不想写作业的朋友方便一下,反正老师也不会仔细检查的
  • 欧几里德算法

    2018-12-03 15:22:39
    欧几里德算法
  • 欧几里德算法称为辗转相除法,用来求已知m、n两个自然数的公因数。结合程序说明一下辗转相除的具体情况。 首先看递归实现: 代码如下:int getcd(int m,int n) { if (m < 0 || n <0) { return 0; } if(m &...
  • 欧几里德算法和扩展欧几里德算法--透彻理解 模P乘法逆元 对于整数a、p,如果存在整数b,满足a×b mod p =1,则说,b是a的模p乘法逆元。
  • 基本算法-欧几里德算法(辗转相除法)

    万次阅读 多人点赞 2021-04-20 08:13:06
    本文介绍一种求解最大公约数常用的算法——欧几里德算法,以下是本篇文章正文内容,包括算法简介、原理及证明和C++代码实现。

    作者:翟天保Steven
    版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处


    前言

           近期购买了一本《图解算法C++》,回顾复习下算法知识。正好借此机会,将我在复习过程中觉得不错或者容易忘记的算法整理下来,可能会帮助到其他想要学习的人。

           本文介绍一种求解最大公约数常用的算法——欧几里德算法,以下是本篇文章正文内容,包括算法简介、原理及证明、算法流程和C++代码实现。


    一、欧几里德算法简介

           欧几里德算法又称辗转相除法,是求解最大公约数常用的一种算法。过程:假设有A和B两个值,A大于B,用其中较大的数A除以较小的数B,再将较小的数B除以得到的余数C(第一次除法所得),又得到一个余数D(第二次除法所得),如此类推,直到最后余数为0时终止该过程,最后的余数就是A和B的最大公约数。


    二、基本原理及证明


    1.基本原理

           两个数的最大公约数是可以同时整除这两个数的最大正整数。 

           设两个数为a、b(a≥b),求a和b最大公约数(Greatest common divisor)gcd(a,b)的步骤如下:

    1. a除以b,得a÷b=q........r1(r1≥0),r1为第一次的余数;
    2. 若r1=0,则gcd(a,b)=b;
    3. 若r1≠0,再用b除以r1,得余数r2;
    4. 如此反复,直到某余数等于0,则该余数就是我们所找的最大公约数gcd(a,b)。

    2.证明

           同样设两个数a和b(a≥b),gcd(a,b)表示两数的最大公约数,r=a mod b,r为a除以b的余数,k为a除以b的商,即a÷b=k......r。

           欧几里德算法能求解最大公约数的原理其实就是证明gcd(a,b)=gcd(b,r),即a和b的最大公约数和b和r的最大公约数是一个。

           证明过程如下:

    1. 令c=gcd(a,b),设a=mc,b=nc;
    2. 由a÷b=k......r可得r=a-kb=mc-knc=(m-kn)c;
    3. 第二步不难看出,c也是r的因数;
    4. 列出b=nc和r=(m-kn)c,如果n和m-kn互质,即两者公约数只有1,则表明c是b和r的最大公约数,后续证明n和m-kn互质;
    5. 假设m-kn和n不是互质,两者有一非零的最大公约数d,且d>1;
    6. 则有m-kn=xd,n=yd,得m=kn+xd=kyd+xd=(ky+x)d,则a=mc=(ky+x)dc,b=nc=ycd,则a与b的一个公约数cd>c,故c不是a与b的最大公约数,这与前面提到的c是a与b的最大公约数假设矛盾;
    7. 故m-kn和n为互质,即c是b和r的最大公约数,且是a和b的最大公约数,得证。

    三、算法描述及流程图

           欧几里德算法求解正整数a和b的最大公因数gcd(a,b),假设a≥b:

           a除以b,若a mod b=0,则gcd(a,b)=b;否则gcd(a,b)=gcd(b,a mod b),递归或循环运算得结果。

           算法流程图如下:

    四、C++代码实现

    // 欧几里德C++实现伪代码
    if ( num1 < num2 )
    {
        temp = num1;
        num1 = num2;
        num2 = temp;
    }
    // 确保num2是较小值,num1是较大值
    
    while ( num2 != 0 )       // 欧几里德算法过程,直到num2(余数)为0时结束循环过程
    {  
        temp = num1 % num2;   // 计算余数
        num1 = num2;
        num2 = temp;          // 将余数作为下一轮的除数
    }
    
    std::cout<<"最大公约数为:"<<num1<<std::endl;


    总结

           以上就是本文所讲的内容,简单介绍了欧几里德算法的原理和实现。

           如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

    展开全文
  • 辗转相除法是古希腊求两个正整数的最大公约数的算法,也叫欧几里德算法,其方法是用较大的数除以较小的数,上面较小的除数和得出的余数构成新的一对数,继续做上面的除法,直到出现能够整除的两个数,其中较小的数...

    题目:

    题目:输入两个正整数m和n,求其最大公约数和最小公倍数

    算法分析

    辗转相除法

    辗转相除法是古希腊求两个正整数的最大公约数的算法,也叫欧几里德算法,其方法是用较大的数除以较小的数,上面较小的除数和得出的余数构成新的一对数,继续做上面的除法,直到出现能够整除的两个数,其中较小的数(即除数)就是最大公约数。以求136和93的最大公约数为例,操作如下:

    168/93=1 ……75

    93/75=1……18

    75/18=4……3

    18/3=6

    所以3就是168和93的最大公约数

    遍历法

    主要代码(辗转相除法)

    void fun(int m,int n){
        int a,b,t;
      	if(m<n){//先将较大的数放到m里面
            t=m;
            m=n;
            n=t;
        }
        a=m;
        b=n;//让a等于较大的数,让b等于较小的数
        while(b!=0){//利用辗转相除法,直到余数b为零结束
            t=a%b;
            a=b;
            b=t;
        }
        printf("最大公约数是:%d\n",a);
        printf("最小公倍数是:%d\n",m*n/b);
    }
    

    主要代码(遍历法)

    void fun2(int m,int n){
    	int x=1,y;//最大公约数x设置为1,最小公倍数y
        int min,max;
        int i;
        
        min=m>n?n:m;
        max=m>n?m:n;
        
        if(max%min==0){//两个数是倍数关系
            printf("最大公约数:%d\n最小公倍数:%d\n",min,max);
        } else{//不成倍数
    		//寻找最大公约数
            for(i=1;i<=min;i++){//从1找到min
                if(max%i==0 && min%i==0) x=i;
            }
            while(max%m!=0 || max%n!=0){//当有一方不能被整除时,继续往后找
                max++;
            }
            y=max;
            printf("最大公约数:%d\n最小公倍数:%d\n",x,y);
        }
    }
    

    今日巩固

    1. 辗转相除法(欧几里德算法)的学习和使用
    2. 对于两个数的换位置,可以使用昨天刚巩固的条件运算符的使用
    3. while循环与for循环的区别与使用
    展开全文
  • 欧几里德与扩展欧几里德算法

    千次阅读 2018-07-28 12:44:14
    欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd
    原文地址为:
    欧几里德与扩展欧几里德算法
    

    欧几里德算法

    欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。

    基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b)。

    第一种证明:

          a可以表示成a = kb + r,则r = a mod b

      假设d是a,b的一个公约数,则有

      d|a, d|b,而r = a - kb,因此d|r

      因此d是(b,a mod b)的公约数

      假设d 是(b,a mod b)的公约数,则

      d | b , d |r ,但是a = kb +r

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

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

     

    第二种证明:

        要证欧几里德算法成立,即证: gcd(a,b)=gcd(b,r),其中 gcd是取最大公约数的意思,r=a mod b
        下面证 gcd(a,b)=gcd(b,r)
        设  c是a,b的最大公约数,即c=gcd(a,b),则有 a=mc,b=nc,其中m,n为正整数,且m,n互为质数
        由 r= a mod b可知,r= a- qb 其中,q是正整数,
        则 r=a-qb=mc-qnc=(m-qn)c
        b=nc,r=(m-qn)c,且n,(m-qn)互质(假设n,m-qn不互质,则n=xd, m-qn=yd 其中x,y,d都是正整数,且d>1
                                                                    则a=mc=(qx+y)dc, b=xdc,这时a,b 的最大公约数变成dc,与前提矛盾,
                                                                     所以n ,m-qn一定互质)
        则gcd(b,r)=c=gcd(a,b)
        得证。

     

    算法的实现:

    最简单的方法就是应用递归算法,代码如下:

    View Code
    1 int gcd(int a,int b)
    2 {
    3 if(b==0)
    4 return a;
    5 return
    6 gcd(b,a%b);
    7 }

    代码可优化如下:

    View Code
    1 int gcd(int a,int b)
    2 {
    3 return b ? gcd(b,a%b) : a;
    4 }

    当然你也可以用迭代形式:

    View Code
     1 int Gcd(int a, int b)
    2 {
    3 while(b != 0)
    4 {
    5   int r = b;
    6   b = a % b;
    7   a = r;
    8 }
    9 return a;
    10 }

     

    扩展欧几里德算法

    基本算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。

    证明:设 a>b。

      1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;

      2,ab!=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;

      根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;

         这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.

       上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。

     

    扩展欧几里德的递归代码:

    View Code
     1 int exgcd(int a,int b,int &x,int &y)
    2 {
    3 if(b==0)
    4 {
    5 x=1;
    6 y=0;
    7 return a;
    8 }
    9 int r=exgcd(b,a%b,x,y);
    10 int t=x;
    11 x=y;
    12 y=t-a/b*y;
    13 return r;
    14 }

     扩展欧几里德非递归代码:

    View Code
     1 int exgcd(int m,int n,int &x,int &y)
    2 {
    3 int x1,y1,x0,y0;
    4 x0=1; y0=0;
    5 x1=0; y1=1;
    6 x=0; y=1;
    7 int r=m%n;
    8 int q=(m-r)/n;
    9 while(r)
    10 {
    11 x=x0-q*x1; y=y0-q*y1;
    12 x0=x1; y0=y1;
    13 x1=x; y1=y;
    14 m=n; n=r; r=m%n;
    15 q=(m-r)/n;
    16 }
    17 return n;
    18 }

     

    扩展欧几里德算法的应用主要有以下三方面:

    (1)求解不定方程;

    (2)求解模线性方程(线性同余方程);

    (3)求解模的逆元;

     

    (1)使用扩展欧几里德算法解决不定方程的办法:

      对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
      上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(p, q)的一组解p0,q0后,p * a+q * b = Gcd(p, q)的其他整数解满足:
      p = p0 + b/Gcd(p, q) * t 
      q = q0 - a/Gcd(p, q) * t(其中t为任意整数)
      至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。

      在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,应该是得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),

      p * a+q * b = c的其他整数解满足:

      p = p1 + b/Gcd(a, b) * t
      q = q1 - a/Gcd(a, b) * t(其中t为任意整数)
      p 、q就是p * a+q * b = c的所有整数解。
     
    用扩展欧几里得算法解不定方程ax+by=c;
    代码如下:
    View Code
    1 bool linear_equation(int a,int b,int c,int &x,int &y)
    2 {
    3 int d=exgcd(a,b,x,y);
    4 if(c%d)
    5 return false;
    6 int k=c/d;
    7 x*=k; y*=k; //求得的只是其中一组解
    8 return true;
    9 }

     

    (2)用扩展欧几里德算法求解模线性方程的方法:

        同余方程 ax≡b (mod n)对于未知数 x 有解,当且仅当 gcd(a,n) | b。且方程有解时,方程有 gcd(a,n) 个解。

        求解方程 ax≡b (mod n) 相当于求解方程 ax+ ny= b, (x, y为整数)

        设 d= gcd(a,n),假如整数 x 和 y,满足 d= ax+ ny(用扩展欧几里德得出)。如果 d| b,则方程

        a* x0+ n* y0= d, 方程两边乘以 b/ d,(因为 d|b,所以能够整除),得到 a* x0* b/ d+ n* y0* b/ d= b。
        所以 x= x0* b/ d,y= y0* b/ d 为 ax+ ny= b 的一个解,所以 x= x0* b/ d 为 ax= b (mod n ) 的解。

        ax≡b (mod n)的一个解为 x0= x* (b/ d ) mod n,且方程的 d 个解分别为 xi= (x0+ i* (n/ d ))mod n {i= 0... d-1}。

        设ans=x*(b/d),s=n/d;

        方程ax≡b (mod n)的最小整数解为:(ans%s+s)%s;

        相关证明:

        证明方程有一解是: x0 = x'(b/d) mod n;
        由 a*x0 = a*x'(b/d) (mod n)
             a*x0 = d (b/d) (mod n)   (由于 ax' = d (mod n))
                     = b (mod n)

        证明方程有d个解: xi = x0 + i*(n/d)  (mod n);
        由 a*xi (mod n) = a * (x0 + i*(n/d)) (mod n)
                                 = (a*x0+a*i*(n/d)) (mod n)
                                 = a * x0 (mod n)             (由于 d | a)
                                 = b

         

    首先看一个简单的例子:

    5x=4(mod3)

    解得x = 2,5,8,11,14.......

    由此可以发现一个规律,就是解的间隔是3.

    那么这个解的间隔是怎么决定的呢?

    如果可以设法找到第一个解,并且求出解之间的间隔,那么就可以求出模的线性方程的解集了.

    我们设解之间的间隔为dx.

    那么有

    a*x = b(mod n);

    a*(x+dx) = b(mod n);

    两式相减,得到:

    a*dx(mod n)= 0;

    也就是说a*dx就是a的倍数,同时也是n的倍数,即a*dx是a 和 n的公倍数.为了求出dx,我们应该求出a 和 n的最小公倍数,此时对应的dx是最小的.

    设a 和 n的最大公约数为d,那么a 和 n 的最小公倍数为(a*n)/d.

    即a*dx = a*n/d;

    所以dx = n/d.

    因此解之间的间隔就求出来了.

        代码如下:

    View Code
     1 bool modular_linear_equation(int a,int b,int n)
    2 {
    3 int x,y,x0,i;
    4 int d=exgcd(a,n,x,y);
    5 if(b%d)
    6 return false;
    7 x0=x*(b/d)%n; //特解
    8 for(i=1;i<d;i++)
    9 printf("%d\n",(x0+i*(n/d))%n);
    10 return true;
    11 }

     

    (3)用欧几里德算法求模的逆元:

           同余方程ax≡b (mod n),如果 gcd(a,n)== 1,则方程只有唯一解。

          在这种情况下,如果 b== 1,同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。

          这时称求出的 x 为 a 的对模 n 乘法的逆元。

          对于同余方程 ax= 1(mod n ), gcd(a,n)= 1 的求解就是求解方程

          ax+ ny= 1,x, y 为整数。这个可用扩展欧几里德算法求出,原同余方程的唯一解就是用扩展欧几里德算法得出的 x 。


    转载请注明本文地址: 欧几里德与扩展欧几里德算法
    展开全文
  • 欧几里德算法的基本原理是:两个数的最大公约数等于它们中较小的数和两数之差的最大公约数。例如: 252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5); 252 − 105 = 147,所以147和105的最大公约数也...

    目录

    1. 算法简介

    2. 算法实现

    2.1 暴力穷举法

    2.2 欧几里德算法


    1. 算法简介

    欧几里德(Euclidean)算法,又被称辗转相除法,是求最大公约数的算法。

    两个数的最大公约数是指能同时整除它们的最大正整数。欧几里德算法的基本原理是:两个数的最大公约数等于它们中较小的数和两数之差的最大公约数。例如:

    252和105的最大公约数是21(252 = 21 × 12;105 = 21 × 5);

    252 − 105 = 147,所以147和105的最大公约数也是21;

    147 − 105 = 63,所以105和63的最大公约数也是21;

    105 − 63 = 42,所以63和42的最大公约数也是21;

    105 − 63 = 42,所以63和42的最大公约数也是21;

    63 − 42 = 21,所以42和21的最大公约数也是21;

    42 − 21 = 21,所以21和21的最大公约数也是21;

    21 − 21 =0,最后剩下21和0,所以252和105的最大公约数是21。

    在这个过程中,较大的数缩小了,所以继续进行同样的计算可以不断缩小这两个数直至其中一个变成零。这时,所剩下的还没有变成零的数就是两数的最大公约数。由辗转相除法也可以推出,两数的最大公约数可以用两数的整数倍相加来表示,如21 = 5 × 105 + (−2) × 252。这个重要的等式叫做贝祖等式(Bézout's identity)。

    2. 算法实现

    求两个整数的最大公约数,最简单的思路就是使用暴力穷举的方法,从最小整数递减,直到这个数可以同时被两个整数除以。同时,我们还可以考虑欧几里德算法,这种方法可以极大的减少运算量。

    2.1 暴力穷举法

    def exhaust():
        #以16与12为例
        for i in range(min(16,12), 1, -1):
            if(12%i==0 and 16%i==0):
                print('gcd is {}.'.format(i))
                break

    想法非常简单,就是选择两个整数中的较小值,逐次递减,直到该值可以被两个整数同时整除,则代表该值为这两个整数的最大公约数。

    这个算法的时间复杂度为O(n)【n为较小数】,特点就是思路简单,遇到较大值则运行时间较长。

    2.2 欧几里德算法

    欧几里德(Euclidean)算法的基本原理就是:两个数的最大公约数等于它们中较小的数和两数之差的最大公约数。因此我们可以不断地将这两个数相减,用新两个数(前面的较小值与差值)替代初值求最大公约数。因此我们会很自然想到用循环来处理这个问题。而值得思考的是,如果一个数是另一个数的几十倍甚至几千倍,一直做差值是不是非常麻烦(比如10000和10),这时候我们应该想到求模运算,它可以代替多次减数相同的差运算,直接得到最终需要的差值(如, 10000 % 10 =0)。

    def euclidean(a, b):
        while(a!=0):
            a, b = b % a, a #此处假设b为较大值,即使不满足条件,第一次运算也会进行值交换
        return b
            

    最近在学习递归,而这个算法很符合递归的思想,下面用递归写一下:

    def euclidean(a=16, b=12):
        if(a!=0):
            a, b = b % a, a
            return euclidean(a,b)
        else:
            return b
    
    print(euclidean(252, 105))

    而对于欧几里德算法的时间复杂度O(log n),特点是算法本身精巧,运算时间短。

    展开全文
  • 辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。 1.问题引入:线段上格点的个数 问题描述:给定平面上的两个格点P1=(x1,y1)和P2=(x2,y2),线段P1P2上,除P1和P2以外一共有几个....
  • 传统欧几里德算法在求解关键方程时需要进行多项式次数的判断,从而造成硬件电路复杂,译码速度下降.通过对综合除法进行推广,提出了一种改进型欧几里德算法,它不需要进行多项式次数的判断,能够降低译码的复杂度,减少...
  • 欧几里德算法复杂度分析

    千次阅读 2018-09-14 21:50:21
    欧几里得算法 function Euclid(a; b) 1: if b = 0 then 2: return a; 3: end if 4: return Euclid(b; a mod b); 复杂度分析: 设a&gt;=ba&gt;=ba >= b ,则有amodb&lt;a2amodb&lt;a2a \mod ...
  • 欧几里德与扩展欧几里德算法 欧几里德算法 欧几里德算法又称辗转相除法用于计算两个整数 a,b 的最大公约数 基本算法设 a=qb+r其中 abqr 都是整数则 gcd(a,b)=gcd(b,r)即 gcd(a,b)=gcd(b,a%b) 第一种证明 a 可以表示...
  • 欧几里德算法是用来求两个正整数最大公约数的算法。是由古希腊数学家欧几里德在其著作《The Elements》中最早描述了这种算法,所以被命名为欧几里德算法。 扩展欧几里德算法可用于RSA加密等领域。 假如需要求 1997 和...
  • 欧几里德C语言算法

    2016-09-02 11:46:35
    欧几里德C语言算法
  • 扩展欧几里德算法:  谁是欧几里德?自己百度去  先介绍什么叫做欧几里德算法  有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na...
  • 采用欧几里德算法编写计算两个整数的最大公约数的函数Gcd()。欧几里德算法,也称辗转相除法。其基本思想是:对正整数a和b,连续进行求余运算,直到余数为0为止,此时非0的除数就是最大公约数。要求如下: (1)在...
  • ------------------------------- 主要执行参考用法:usage_extendedEuclidean.m 还请在文件夹 [document] 中找到简化示例。 警告:仅供参考。 如果该实用程序有更优化的方法,请不要犹豫,建议并向作者发送反馈...
  • 欧几里德算法的证明

    千次阅读 多人点赞 2016-07-08 14:46:16
    在学习算法的过程中,与欧几里德算法来了一次邂逅,于是又去学习了一下。。。 欧几里德算法又称辗转相除法,用于计算两个数的最大公约数。 定理: 设a=qb+r,其中a,b,q,r都是正整数,则gcd(a,b)=gcd(b,r),即gcd...
  • 转载自:扩展欧几里德算法详解作者:zhj5chengfeng %%% 以下为原文 扩展欧几里德算法谁是欧几里德?自己百度去先介绍什么叫做欧几里德算法有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的...
  • 欧几里德算法描述:欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:定理:gcd(a,b) = gcd(b,a mod b)证明:a可以表示成a = kb + r,则r = a mod b假设d是a,b的一个公...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,141
精华内容 5,656
关键字:

欧几里德算法