基本概念
如果数a能被数b整除,a就叫做b的倍数,b就叫做a的约数。约数和倍数都表示一个整数与另一个整数的关系,不能单独存在。如只能说16是某数的倍数,2是某数的约数,而不能孤立地说16是倍数,2是约数。
"倍"与"倍数"是不同的两个概念,"倍"是指两个数相除的商,它可以是整数、小数或者分数。"倍数"只是在数的整除的范围内,相对于"约数"而言的一个数字的概念,表示的是能被某一个自然数整除的数。
几个整数中公有的约数,叫做这几个数的公约数;其中最大的一个,叫做这几个数的最大公约数。例如:12、16的公约数有1、2、4,其中最大的一个是4,4是12与16的最大公约数,一般记为(12,16)=4。12、15、18的最大公约数是3,记为(12,15,18)=3。
几个自然数公有的倍数,叫做这几个数的公倍数,其中最小的一个自然数,叫做这几个数的最小公倍数。例如:4的倍数有4、8、12、16,……,6的倍数有6、12、18、24,……,4和6的公倍数有12、24,……,其中最小的是12,一般记为[4,6]=12。12、15、18的最小公倍数是180。记为[12,15,18]=180。若干个互质数的最小公倍数为它们的乘积的绝对值。
求法质因数分解法质因数分解法:把每个数分别分解质因数,再把各数中的全部公有质因数提取出来连乘,所得的积就是这几个数的最大公约数。
例如:求24和60的最大公约数,先分解质因数,得24=2×2×2×3,60=2×2×3×5,24与60的全部公有的质因数是2、2、3,它们的积是2×2×3=12,所以,(24,60)=12。
把几个数先分别分解质因数,再把各数中的全部公有的质因数和独有的质因数提取出来连乘,所得的积就是这几个数的最小公倍数。
例如:求6和15的最小公倍数。先分解质因数,得6=2×3,15=3×5,6和15的全部公有的质因数是3,6独有质因数是2,15独有的质因数是5,2×3×5=30,30里面包含6的全部质因数2和3,还包含了15的全部质因数3和5,且30是6和15的公倍数中最小的一个,所以[6,15]=30。
短除法短除法:短除法求最大公约数,先用这几个数的公约数连续去除,一直除到所有的商互质为止,然后把所有的除数连乘起来,所得的积就是这几个数的最大公约数。
短除法求最小公倍数,先用这几个数的公约数去除每个数,再用部分数的公约数去除,并把不能整除的数移下来,一直除到所有的商中每两个数都是互质的为止,然后把所有的除数和商连乘起来,所得的积就是这几个数的最小公倍数,例如,求12、15、18的最小公倍数。
短除法的本质就是质因数分解法,只是将质因数分解用短除符号来进行。
短除符号就是除号倒过来。短除就是在除法中写除数的地方写两个数共有的质因数,然后落下两个数被公有质因数整除的商,之后再除,以此类推,直到结果互质为止(两个数互质)。
而在用短除计算多个数时,对其中任意两个数存在的因数都要算出,其它没有这个因数的数则原样落下。直到剩下每两个都是互质关系。
求最大公因数便乘一边,求最小公倍数便乘一圈。
无论是短除法,还是分解质因数法,在质因数较大时,都会觉得困难。这时就需要用新的方法。
辗转相除法辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法。
例如,求(319,377):
∵ 319÷377=0(余319)
∴(319,377)=(377,319);
∵ 377÷319=1(余58)
∴(377,319)=(319,58);
∵ 319÷58=5(余29)
∴ (319,58)=(58,29);
∵ 58÷29=2(余0)
∴ (58,29)= 29;
∴ (319,377)=29。
可以写成右边的格式。
用辗转相除法求几个数的最大公约数,可以先求出其中任意两个数的最大公约数,再求这个最大公约数与第三个数的最大公约数,依次求下去,直到最后一个数为止。最后所得的那个最大公约数,就是所有这些数的最大公约数。
更相减损法更相减损法:也叫更相减损术,是出自《九章算术》的一种求最大公约数的算法,它原本是为约分而设计的,但它适用于任何需要求最大公约数的场合。
《九章算术》是中国古代的数学专著,其中的“更相减损术”可以用来求两个数的最大公约数,即“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。”
翻译成现代语言如下:
第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。
其中所说的“等数”,就是最大公约数。求“等数”的办法是“更相减损”法。所以更相减损法也叫等值算法。
例1.用更相减损术求98与63的最大公约数。
解:由于63不是偶数,把98和63以大数减小数,并辗转相减:
98-63=35
63-35=28
35-28=7
28-7=21
21-7=14
14-7=7
所以,98和63的最大公约数等于7。
这个过程可以简单的写为:
(98,63)=(35,63)=(35,28)=(7,28)=(7,21)=(7,14)=(7,7)=7.
例2.用更相减损术求260和104的最大公约数。
解:由于260和104均为偶数,首先用2约简得到130和52,再用2约简得到65和26。
此时65是奇数而26不是奇数,故把65和26辗转相减:
65-26=39
39-26=13
26-13=13
所以,260与104的最大公约数等于13乘以第一步中约掉的两个2,即13*2*2=52。
这个过程可以简单地写为:
(260,104)(/2/2) =>(65,26)=(39,26)=(13,26)=(13,13)=13. (*2*2) => 521
比较辗转相除法与更相减损术的区别
(1)都是求最大公因数的方法,计算上辗转相除法以除法为主,更相减损术以减法为主,计算次数上辗转相除法计算次数相对较少,特别当两个数字大小区别较大时计算次数的区别较明显。
(2)从结果体现形式来看,辗转相除法体现结果是以相除余数为0则得到,而更相减损术则以减数与差相等而得到。23
常用结论在解有关最大公约数、最小公倍数的问题时,常用到以下结论:
(1)如果两个自然数是互质数,那么它们的最大公约数是1,最小公倍数是这两个数的乘积。
例如8和9,它们是互质数,所以(8,9)=1,[8,9]=72。
(2)如果两个自然数中,较大数是较小数的倍数,那么较小数就是这两个数的最大公约数,较大数就是这两个数的最小公倍数。
例如18与3,18÷3=6,所以(18,3)=3,[18,3]=18。
(3)两个整数分别除以它们的最大公约数,所得的商是互质数。
例如8和14分别除以它们的最大公约数2,所得的商分别为4和7,那么4和7是互质数。
(4)两个自然数的最大公约数与它们的最小公倍数的乘积等于这两个数的乘积。
例如12和16,(12,16)=4,[12,16]=48,有4×48=12×16,即(12,16)× [12,16]=12×16。
(5)GCD(a,b) is the smallest positive linear combination of a and b. a与b的最大公约数是最小的a与b的正线性组合,即对于方程xa+yb=c来说,若x,a,y,b都为整数,那么c的最小正根为gcd(a,b).
历史发展在求解最大公约数的几种方法中,辗转相除法最为出名。辗转相除法是仍然在使用的历史最悠久的算法之一。它首次出现于几何原本(卷7命题1–2、卷10命题2–3)(大约公元前300年)。在卷7中用于整数,在卷10中用于线段的长度(也就是所说的实数,但是当时未有实数的概念)。卷10中出现的算法是几何的,两段线段a和b的最大公约数是准确测量a和b的最大长度。
这个算法可能并非欧几里得发明,而仅仅是将先人的结果编进他的几何原本。数学家、历史学家范德瓦尔登认为卷7的内容可能来自毕达哥拉斯学院出身的数学家写的关于数论的教科书。辗转相除法是被大约公元前375年的欧多克斯发现的,但也有可能更早之前就已经存在,因为欧几里得和亚里士多德的这两位历史名人著作中都出现了ἀνθυφαίρεσις一词(anthyphairesis, 意为“辗转相减”),
几个世纪之后,辗转相除法又分别被中国人和印度人独立发现,主要用来解天文学中用到的丢番图方程以及指定准确的历法。5世纪末,印度数学家、天文学家阿里亚哈塔可能是因为辗转相除法在解丢番图方程时的高效率而称它为“粉碎机”。因为在中国,孙子算经中出现了此算法的一个特例中国剩余定理,但是辗转相除法的完整表述直到1247年秦九韶的数学九章中才出现。在欧洲,辗转相除法首次出现于克劳德·巴希特(英语:Claude Gaspard Bachet de Méziriac)的著作Problèmes plaisants et délectables的第二版在欧洲,辗转相除法广泛使用于丢番图方程和连分数。后来,英国数学家桑德森(英语:Nicholas Saunderson)将扩展欧几里得算法作为罗杰科茨(英语:Roger Cotes)对计算连分数的方法的研究发表。
19世纪,辗转相除法孕育出了一些新的数系,如高斯整数和艾森斯坦整数。1815年,高斯用辗转相除法证明高斯整数的分解是惟一的,他的研究发表于1832年。高斯在他的《算数研究》(published 1801)中,作为处理连分数的方法提到了这个算法。约翰·狄利克雷是第一个将辗转相除法作为数论的基础的数学家。狄利克雷提出,数论中的很多结论,如分解的惟一性,在任何使辗转相除法成立的数系中有效。狄利克雷的观点被理查德·戴德金修改和推广,他用辗转相除法研究代数整数。戴德金是第一个用高斯整数的分解惟一性证明费马平方和定理的数学家。戴德金还率先定义了欧几里得整环的概念。19世纪末,辗转相除法的辉煌逐渐被戴德金的理想取代。
辗转相除法的其他应用发展于19世纪。1829年,施图姆将辗转相除法用于施图姆序列(用于确定多项式的不同实根的个数的方法)。
辗转相除法是历史上第一个整数关系算法(英语:integer relation algorithm),即寻找两数的整数关系的算法。 近年来,出现了一些新颖的整数关系算法,如埃拉曼·弗格森(英语:Helaman Ferguson)和福尔卡德于1979年发表的弗格森-福尔卡德算法、以及与它相关的LLL算法(英语:Lenstra–Lenstra–Lovász lattice basis reduction algorithm)、HJLS算法以及PSLQ算法(英语:PSLQ algorithm)。
1969年,科尔(Cole)和戴维(Davie)基于辗转相除法创造了一种二人游戏,叫做欧几里得游戏。这个游戏有最优策略。游戏开始于两列分别为a和b个棋子组成的序列,玩家轮流从较长一列中取走较短一列棋子数量的m倍的棋子。如果两列棋子a和b分别由x和y个棋子组成,其中x大于y,那么玩家可以序列a的棋子数量减少为自然数x − my。最后率先将一列棋子清空的玩家胜出。
扩展欧几里得算法
扩展欧几里德算法:扩展欧几里得算法(又称扩充欧几里得算法)是用来解某一类特定的不定方程的一种方法,常用用来求解模线性方程及方程组。扩展的欧几里得算法可以用来计算模逆元,而模逆元在公钥密码学中占有举足轻重的地位。4
基本算法:对于不完全为 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,所以递归可以结束。5
Stein算法
欧几里德算法是计算两个数最大公约数的传统算法,无论从理论还是从实际效率上都是很好的。但是却有一个致命的缺陷,这个缺陷在素数比较小的时候一般是感觉不到的,只有在大素数时才会显现出来。
Stein算法由J. Stein 1961年提出,这个方法也是计算两个数的最大公约数。和欧几里德算法算法不同的是,Stein算法只有整数的移位和加减法,这对于程序设计者是一个福音。6
Stein算法:
设置A1=A、B1=B和C1=1
1、如果An=0,Bn*Cn是最大公约数,算法结束
2、如果Bn=0,An*Cn是最大公约数,算法结束
3、如果An和Bn都是偶数,则An+1=An/2,Bn+1=Bn/2,Cn+1=Cn*2(注意,乘2只要把整数左移一位即可,除2只要把整数右移一位即可)
4、如果An是偶数,Bn不是偶数,则An+1=An/2,Bn+1=Bn,Cn+1=Cn (很显然啦,2不是奇数的约数)
5、如果Bn是偶数,An不是偶数,则Bn+1=Bn/2,An+1=An,Cn+1=Cn (很显然啦,2不是奇数的约数)
6、如果An和Bn都不是偶数,则An+1=|An-Bn|,Bn+1=min(An,Bn),Cn+1=Cn
7、n加1,转步骤1
考虑欧几里德算法,最恶劣的情况是,每次迭代a=2b-1,这样,迭代后,r=b-1。如果a小于2N,这样大约需要4N次迭代。而考虑Stein算法,每次迭代后,显然A(n+1)B(n+1)≤AnBn/2,最大迭代次数也不超过4N次。也就是说,迭代次数几乎是相等的。但是,需要注意的是,对于大素数,试商法将使每次迭代都更复杂,因此对于大素数Stein将更有优势。7
性质重要性质:gcd(a,b)=gcd(b,a) (交换律)
gcd(-a,b)=gcd(a,b)
gcd(a,a)=|a|
gcd(a,0)=|a|
gcd(a,1)=1
gcd(a,b)=gcd(b, a mod b)
gcd(a,b)=gcd(b, a-b)
如果有附加的一个自然数m,
则: gcd(ma,mb)=m * gcd(a,b) (分配律)
gcd(a+mb ,b)=gcd(a,b)
如果m是a和b的最大公约数,
则: gcd(a/m ,b/m)=gcd(a,b)/m
在乘法函数中有:
gcd(ab,m)=gcd(a,m) * gcd(b,m)
两个整数的最大公约数主要有两种寻找方法:
* 两数各分解质因数,然后取出同样有的质因数乘起来
*辗转相除法(扩展版)
和最小公倍数(lcm)的关系:
gcd(a, b) * lcm(a, b) = ab
a与b有最大公约数,
两个整数的最大公因子可用于计算两数的最小公倍数,或分数化简成最简分数。
两个整数的最大公因子和最小公倍数中存在分配律:
* gcd(a, lcm(b, c)) = lcm(gcd(a, b), gcd(a, c))
* lcm(a, gcd(b, c)) = gcd(lcm(a, b), lcm(a, c))
在坐标里,将点(0, 0)和(a, b)连起来,通过整数坐标的点的数目(除了(0, 0)一点之外)就是gcd(a, b)。
程序实现PASCALprogramzuidagongyueshu;varm,n,a,b,r:integer;begin//主程序write('Inputm,n=');readln(m,n);a:=m;b:=n;repeatr:=amodb;a:=b;b:=r;untilr b=0;writeln('Thegreatestcommondivideis:',a);end.【递归算法】
programgcd;vark,a,b:integer;functiongcd(a,b:integer):integer;beginifamodb=0thenexit(b)elsegcd:=gcd(b,amodb);end;beginreadln(a,b);k:=gcd(a,b);writeln(k);end.C语言#includeint main(){ int m,n,i; scanf("%d",&m); scanf("%d",&n); for(i=m;i>=1;i--) if(m%i==0 && n%i==0) break; printf("%d\n",i); return 0; }递归算法1.C语言程序如下:#include #include /* * 最大公约数的递归: * 1、若a可以整除b,则最大公约数是b * 2、如果1不成立,最大公约数便是b与a%b的最大公约数 * 示例:求(140,21) * 140%21 = 14 * 21%14 = 7 * 14%7 = 0 * 返回7 * */int gcd(int a,int b){ if(a%b==0) return b; return gcd(b,a%b);}int main(void){ int a=10,b=8; scanf("%d %d",&a,&b); printf("GCD: A=>%d, B=>%d (A,B)=%d\n",a,b,gcd(a,b)); return 0;}C++:int gcd(inta,intb){ int temp; while(b) { /*利用辗除法,直到b为0为止*/ temp = b; b = a % b; a = temp; } return a;} 分数的最大公约数为:例(5/6,5/9)=(5,5)/【6,9】=5/18递归算法(c++实现)2.C++程序如下:#includeint GCD(int a,int b){ return a%b?gcd(b,a%b):b;}int main(){ int x,y; scanf("%d%d",&x,&y); printf("%d",GCD(x,y)); return 0;}3.辗转相除法(Matlab实现)function GCD=Euclid(m,n) %辗转相除法(即欧几里德算法)。r=mod(m,n);while r~=0 r=mod(m,n); m=n; n=r;endGCD=m;>> m=319;n=377;Euclid(m,n)ans = 294.递归算法(Python实现)def gcd(n1,n2): """greatest common divisor function """ if(n1%n2 == 0): return n2 return gcd(n2,n1%n2)