想知道为什么欧几里得算法有效吗?我们已经知道任何一对积极的整数s有一个最大的公约数; 诀窍是找到它。
从两个不同的数字开始,n个1和n个2,我们可以把它们表示为k1d日和k2d日,哪里d日是最大的公约数。从定义最大公约数,k1和k2是相对质数.
在不失一般性的情况下,我们可以假设k1>k个2> 0.然后我们可以表达k1就k2:
k1=c1k2+k个三这样的话c(c)1> 0和k2>k个三> 0.
不仅如此,k三相对于k2,因为d日2d日(其中d日2是最大公约数k2和k三)将是的公约数n个1和n个2更大的比d日,与我们的定义相反。
我们可以反复重复上述步骤:
k2=c2k三+k个4
k三=c三k4+k个5
依此类推,得到一系列级联k是这样的k我>ki+1> 0,以及其中k我和ki+1是相对最好的(如果不是,d日我将分ki-1型 那么它就不是相对的素数到k我).
最终, 我们必须达到米这样的话k米= 1.
然后km-1个=km-1个k米+ 0. 反向工作,我们可以分配n个我=k我d日并得到欧几里德算法的传统表示:
n个1=c1n个2+n个三
n个2=c2n个三+n个4
...
n个m-2个=cm-2个n个m-1个+n个米
n个m-1个=cm-1个n个米+ 0.
哪里d=n米当然,如果n个米= 1, n个1和n个2相对而言素数。
对原始算法稍作修改,您可以节省一些某些情况下的步骤。由于算法对较小的数字只需较少的步骤,因此您应该使用“最小正余数”每个步骤。也就是说,如果步骤我代表:n个我=dki+1*c(c)我+达克i+2个
我们也可以说
n个我=dki+1*(c)我+1) -d(k)i+1-k个i+2个).
自从ki+1> ki+1-k个i+2个> 0,继续执行中的算法ki+1-k个i+2个将也会提供正确的结果,并且在任何时候都会保存一个步骤ki+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<<“euclids<”<<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;}//宣布};//结构欧几里得