您的位置:首页 > 其它

最小公倍数、最大公约数的算法和辗转相除法

2016-05-20 16:54 435 查看
转载请标明出处:http://blog.csdn.net/xx326664162/article/details/51463006 文章出自:薛瑄的博客

你也可以查看我的其他同类文章,也会让你有一定的收货!

求最小公倍数算法:

最小公倍数:数论中的一种概念,两个整数公有的倍数成为他们的公倍数,其中一个最小的公倍数是他们的最小公倍数,同样地,若干个整数公有的倍数中最小的正整数称为它们的最小公倍数

最小公倍数=两整数的乘积÷最大公约数

证明的话,我可能写法不会太严谨,还是举个栗子吧:

求最小公倍数的常规方法:

首先把两个数的质因数写出来,最小公倍数等于它们所有的质因数的乘积(如果有质因数相同,则除去相同的质因数一次)。

比如求45和30的最小公倍数。

45=3*3*5

30=2*3*5

最小公倍数等于2*3*3*5=90,用最大公约数15(3*5)乘以各自的其他部分的质因数(2和3),既保障数字是最小的,也保障是他们共同的倍数

所以最小公倍数也可以表示为:3*3*5*2*3*5÷3*5 = 90

求最大公约数算法:

最小公约数:两个整数公有的约数成为他们的公约数,其中一个最大的公约数是他们的最大公约数

辗转相除法

1、用除法实现辗转相除法:

有两整数a和b:

① a%b得余数c

② 若c=0,则b即为两数的最大公约数

③ 若c≠0,则a=b,b=c,再回去执行①

例如求27和15的最大公约数过程为:

27÷15 余1215÷12余312÷3余0因此,3即为最大公约数

C语言描述

void main()   /*  辗转相除法求最大公约数 */
{
int m, n, a, b, t, c;
printf("Input two integer numbers:\n");
scanf("%d%d", &a, &b);
m=a;   n=b;
while(b!=0)  /* 余数不为0,继续相除,直到余数为0 */
{ c=a%b; a=b;  b=c;}
printf("The largest common divisor:%d\n", a);
printf("The least common multiple:%d\n", m*n/a);
}


⑵ 用减法实现辗转相除法

有两整数a和b:

① 若a>b,则a=a-b

② 若a< b,则b=b-a

③ 若a=b,则a(或b)即为两数的最大公约数

④ 若a≠b,则再回去执行①

例如求27和15的最大公约数过程为:

27-15=12( 15>12 ) 15-12=3( 12>3 )

12-3=9( 9>3 ) 9-3=6( 6>3 )

6-3=3( 3==3 )

因此,3即为最大公约数

C语言描述:

void main ( )  /* 相减法求最大公约数 */
{
int m, n, a, b, c;
printf("Input two integer numbers:\n");
scanf ("%d,%d", &a, &b);m=a; n=b;
/* a, b不相等,大数减小数,直到相等为止。*/
while ( a!=b)
if (a>b)  a=a-b;
else  b=b-a;
printf("The largest common divisor:%d\n", a);
printf("The least common multiple:%d\n", m*n/a);
}


辗转相除法的正确性证明

计算过程

辗转相除法是一种递归算法,每一步计算的输出值就是下一步计算时的输入值。设k表示步骤数(从0开始计数),算法的计算过程如下:

规定rk−1 为除数和rk−2为被除数,因为每一步计算出的余数都在不断减小,所以,rk−1 小于rk−2。

把上一次的除数和余数,当做这次的被除数和除数。

在第k步中,算法计算出满足以下等式的商qk和余数 rk:

rk−2 = qk rk−1 + rk

其中0 ≤ rk < rk−1。也就是rk−2要不断减去rk−1直到比rk−1小。

为求简明,以下只说明如何求两个非负整数a和b的最大公约数(负数的情况是简单的)。

第1步计算时(k = 0),设r−2和r−1分别等于a和b,

第2步(此时k = 1)时计算r−1(即b)和r0(第一步计算产生的余数)相除产生的商和余数,

以此类推。整个算法可以用如下等式表示:

a = q0 b + r0

b = q1 r0 + r1

r0 = q2 r1 + r2

r1 = q3 r2 + r3



如果有a < b,算法的第一步实际上会把两个数字交换,因为这时a除以b所得的商q0会等于0,余数r0则等于a。然后,算法的第二步便是把b除以a,再计算所得之商和余数。所以,对于k ≥ 0总有rk< rk−1,即运算的每一步中得出的余数一定小于上一步计算的余数。

由于每一步的余数都在减小并且不为负数,必然存在第N步时rN等于0,使算法终止,rN−1就是a和b的最大公约数。其中N不可能无穷大,因为在r0和0之间只有有限个自然数。

正确性的证明

辗转相除法的正确性可以分成两步来证明。

在第一步,我们会证明算法的最终结果rN−1同时整除a和b。因为它是一个公约数,所以rN−1<=最大公约数g。

在第二步,我们证明g能整除rN−1。所以g<=rN−1。

两个不等式只在rN−1 = g是同时成立。

具体证明如下:

1、证明rN−1同时整除a和b:

因为余数rN是0,rN−1能够整除rN−2:

rN−2 = qN rN−1

因为rN−1能够整除rN−2,所以也能够整除rN−3:

rN−3 = qN−1 rN−2 + rN−1

同理可证rN−1可以整除所有之前步骤的余数,包括a和b,即rN−1是a和b的公约数,rN−1 ≤ g。

2、证明最大公约数g能整除rN−1:

根据定义,a和b可以写成g的倍数:a = mg、b = ng,其中m和n是自然数。

因为r0 = a − q0b = mg − q0ng = (m − q0n)g,所以g整除r0。

同理可证g整除每个余数r1, r2, …, rN-1。因为最大公约数g整除rN−1,因而g ≤ rN−1。

因为第一步的证明告诉我们rN−1 ≤ g,所以g = rN−1。

参考:

https://zh.wikipedia.org/wiki/%E8%BC%BE%E8%BD%89%E7%9B%B8%E9%99%A4%E6%B3%95

http://blog.csdn.net/iwm_next/article/details/7450424

http://blog.csdn.net/yangzhongblog/article/details/10255259
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: