想知道为什么欧几里得算法有效吗?

我们已经知道任何一对积极的整数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+k5

依此类推,得到一系列级联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个m-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;}//宣布}; // 结构欧几里德