给定两个整数,a和b,返回其最大公约数,gcd公司(a、b)。这可能是第一个已知的算法可以追溯到两千多年前!通常归因于欧几里得.

如果a>b掉期(a,b)而a>0{x=b国防部b=aa=x}返回b

(严格地说,这只适用于自然数;您应该首先使用绝对值a和b的…)

很明显,这个算法 终止因为每次经过a被指定为“国防部a“运算,它必然减少它。a总是非负的,因此可能只发生有限次传递。

它的工作方式很简单。每次传球开始时gcd公司a和b的值与gcd公司原始输入。为了说明这一点,我们注意到b国防部a是b减去a倍数的;因此,任何常见的除数a和b是常见的除数a和b的国防部a、 和反之亦然,所以gcd公司s必须相同。在最后一步,它返回b,这是正确的!(gcd公司(0,b)=b,因为任何自然数都除以0——这不仅仅是一个诡辩:考虑最后一步,它从b开始,是a的倍数)

请注意,此算法适用于任何戒指,不仅仅是整数第条。

历史上(在某种程度上数学上),欧几里得算法这真的很有趣,因为它仍然是我们今天拥有的最好的算法。事实上,它广泛用于因式分解(请参见因子分解算法)和素性测试,两个现代、快节奏的数学领域。非常令人印象深刻,考虑到它起源放在周围公元前200年.

一些人并不知道,通过几个额外的步骤,您可以欧几里得算法不仅要找到最大公分母 两个整数b条c(c),也包括x个对于其中bx公司+塞浦路斯=。我们这里利用的事实是gcd公司两个(或多个)数字的最小正数线性组合.

一个简单的演示,您可能可以将其转换为C类比我能做到的更快:

q个第页x个71    1    01   50    0    12   21    1   -12    8   -2    31    5    5   -71    3   -7   101    2   12  -171  -19   27gcd(71,50)=1=(71)(-19)+(50)(27)
每行需要四次快速计算:
  • q个i+1(输入+1)=地板(r)/第页i+1(输入+1))
  • 第页i+1(输入+1)=ri-1号机组-q个*第页
  • x个i+1(输入+1)=xi-1号机组-q个*x个
  • i+1(输入+1)=yi-1型-q个*年
当然,r0和r1是b和c,按大小递减

欧几里得算法如果你没有例子所以我准备了一个。我希望它能有所帮助。

问题:查找最大公约数数字636和483。

解决方案:本质上,这意味着“找到一个与636和483相等的最大值”。您可以采取以下步骤:
636=483*1+153/*153是余数636÷483*/483 = 153 * 3 + 24153 =  24 * 6 + 924  =   9 * 2 + 69   =   6 * 1 + 36=3*2+0/*余数=0时停止*/所以3是636和483的GCD。
任何问题、建议或错误,请给我留言。
想知道为什么欧几里得算法有效吗?

我们已经知道任何一对积极的整数s有一个最大的公约数; 诀窍是找到它。

从两个不同的数字开始,n个1n个2,我们可以把它们表示为k个1d日k个2d日,哪里d日是最大的公约数。从定义最大公约数,k个1k个2相对质数.

在不失一般性的情况下,我们可以假设k个1>k个2> 0.然后我们可以表达k个1依据k个2:

k个1=c1k个2+k个这样的话c(c)1> 0k个2>k个> 0.

不仅如此,k个相对于k个2,因为d日2d日(其中d日2最大公约数k个2k个)将是的公约数n个1n个2更大的d日与我们的定义相反。

我们可以反复重复上述步骤:

k个2=c2k个+k4
k个=ck个4+k个5

依此类推,得到一系列级联k个是这样的k个>k个i+1(输入+1)> 0,以及其中k个k个i+1(输入+1)是相对最好的(如果不是,d日k个i-1号机组 那就不是最好的了k个).

最终, 我们必须达到这样的话k个= 1.

然后k个m-1个=km-1个k个+ 0反向工作,我们可以分配n个=kd日并得到欧几里得算法的传统表示:

n个1=c1n个2+n个
n个2=c2n个+n个4
。。。
n个m-2个=cm-2个n个米-1+n个
n个m-1个=cm-1个n个+ 0.

哪里d=n当然,如果n个= 1, n个1n个2相对而言素数。



对原始算法稍作修改,您可以节省一些某些情况下的步骤。由于算法对较小的数字只需较少的步骤,因此您应该使用“最小正余数”每个步骤。也就是说,如果步骤代表:

n个=dki+1(输入+1)*c+达克i+2个

我们也可以说

n个=dki+1(输入+1)*(c)+1) -d(k)i+1(输入+1)-k个i+2个).

自从k个i+1(输入+1)> k个i+1(输入+1)-k个i+2个> 0,继续执行中的算法k个i+1(输入+1)-k个i+2个也会提供正确的结果,并且在任何时候都会保存一个步骤k个i+1(输入+1)-k个i+2个<ki+2个


将修改应用于施米克的示例:

636 = 483 * 1 + 153483 = 153 * 3 +  24153=24*6+924=9*3-3/*3小于6*/9=3*3+0/*停止*/
同样,3是636和483的GCD,但我们节省了一步。让我们试试更难的一对数字:
973 = 593 * 1 + 380593 = 380 * 1 + 213380 = 213 * 1 + 167213 = 167 * 1 +  46167 =  46 * 3 +  29 46 =  29 * 1 +  17 29 =  17 * 1 +  12 17 =  12 * 1 +   5 12 =   5 * 2 +   2  5 =   2 * 2 +   12=2*1+0/*不必要的最后一步*/
表明973和593相对质数。这将变为:
 
973 = 593 * 2 - 213593 = 213 * 3 -  46213 =  46 * 5 -  17 46 =  17 * 3 -   5 17 =   5 * 3 +   2  5 =   2 * 2 +   1  2 =   2 * 1 +   0
保存4个步骤。请注意,第二个中出现的大多数数字序列也出现在第一个序列中,但更早了一步。

最后,还有一个小消息:欧几里德算法的最坏情况斐波那契数列.为什么?系数总是1,余数收缩的时间比其他数长数字。而且他们总是相对优秀的,该死的!


编译时C++中的欧几里得算法,使用递归模板是的,我知道它也完成了在这里但许多编译器都会被简单版本阻塞。此版本还使用“最小正余数”快捷方式来保存模板专门化。

#包括<ostream>使用std::ostream;使用std::endl;#如果定义STATIC_CONST_WORKS_THE_WAY_IT_SHOULD#定义MAGIC_NUM(n,value)static const unsigned long n=value#其他////枚举黑客宏//#定义MAGIC_NUM(n,value)枚举n##_{n=value}#结尾模板<无符号长i,无符号长j>结构欧几里德{MAGIC_NUM(较小,(i<j)?i: j));MAGIC_NUM(较大,(i<j)?:j: i);MAGIC_NUM(d,(小于等于0)?较小:1));MAGIC_NUM(r,(小于等于0)?大于%d:0);MAGIC_NUM(r2,较小的-r);磁_数值(lpr,(r2<r)?r2:r);typedef欧几里德<leser,lpr>recur_type;MAGIC_NUM(gcd,(lpr>0)?(lpr>1)?复发类型::gcd:1):较小);磁_数值(lcm,大于*(小于/gcd));静态ostream公告(ostream&os){os<<“欧几里得<”<<i<<“,”<j<<“>”<endl;//os<<“d:”<<d<<endl;//os<<“m:”<<m<<endl;//os<<“r:”<<r<<endl;//os<<“lpr:”<<lpr<<endl;//os<<“gcd:”<<gcd<<endl;//os<<“lcm:”<<lcm<<endl;如果(lpr>0)recur_type::announce(os);返回os;}//宣布}; // 结构欧几里德

欧几里德算法有一个非常优雅的 递归的定义:
  • 基本情况:GCD(A,0)=A
  • 隐匿案例:GCD(A,B)=GCD(B,A%B)
这当然会导致单线算法在大多数情况下高级程序设计语言。功能是尾部递归,所以如果你有一个好编译器调用堆栈是建立起来的。

登录登记在这里写点什么或联系作者。