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

转载请标明出处: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

关注我的公众号,轻松了解和学习更多技术
这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值