最大公约数&最小公倍数探讨
2013-07-17 17:02
232 查看
求解最大公约数和最小公倍数,应该算是很基本的问题了。也正因为这样,第一篇算法类博客就来研究研究它了。
麻雀虽小,五脏俱全。 也能从中学点东西。
下面谈谈我对这问题的认识。
首先,看似是2个不同的问题,其实,就是一个算法。即求最大公约数,因为,通过观察,我们有以下结论。
a,b的最大公约数是m,最小公倍数是n。 则有以下结论: a*b=m*n。
如4,6 ----- 最大公约数2,最下公倍数12 满足4*6 = 2*12.
下面通过公式证明:
假设x=abc, y=bcd,
则最小公倍数为abcd, 最大公约数为bc
最小公倍数为abcd=最大公约数为bc*x/bc*y/bc =xy/bc。
也就是说 最小公倍数=两数之积/最大公约数
所以,我们通过求最大公约数就能解决这两个问题了。 下***体分析如何求解最大公约数。
2.a%b得余数r
3.如果r=0,则b为两数的最大公约数。
4.如果r≠0,则另a=b,b=r,再从第二步执行。
5.直到r=0,此时b为两数的最大公约数。
15除25余15------- 25除15余10--------15除10余5-----------10除5余0. 故最大公约数为5.
1. 若a>b,则a=a-b
2. 若a<b,则b=b-a
3. 若a=b,则a(或b)即为两数的最大公约数
4. 若a≠b,则再回去执行①
5. 直到a=b。此时a即为两数的最大公约数
求98,63的最大公约数:
98-63=35
63-35=28
35-28=7
28-7=21
21-7=14
14-7=7
所以,98和63的最大公约数等于7。
2. index索引从2开始到smaller遍历,发现有没有数据可以同时被两者整除,有则更新数据
3. 循环结束后,获取最大的公约数
首先 smaller=4,larger=6。 index=2, smaller%index==0 并且 larger%index==0, 故最大公约数为index=2.
到此,常见的,较好的3种算法都已经介绍好了。在实际应用中,我们的选择,还是视情况而定。下面做个小小的比较。
更相减损术和辗转相除法的主要区别在于前者所使用的运算是“减”,后者是“除”。从算法思想上看,两者并没有本质上的区别,但是在计算过程中,如果遇到一个数很大,另一个数比较小的情况,可能要进行很多次减法才能达到一次除法的效果,从而使得算法的时间复杂度退化为O(N),其中N是原先的两个数中较大的一个。相比之下,辗转相除法的时间复杂度稳定于O(logN)。
算法一说,各有各的好处,各有各的使用对象。希望,在充分掌握这三种方法的基础上,加以选择。
下面补充一个多数最大公约数的算法。 原理类似,利用辗转相除法。
今天就先写到这里。 希望,对你,对我自己,都能有所帮助。
如有错误,欢迎指正。
麻雀虽小,五脏俱全。 也能从中学点东西。
下面谈谈我对这问题的认识。
首先,看似是2个不同的问题,其实,就是一个算法。即求最大公约数,因为,通过观察,我们有以下结论。
a,b的最大公约数是m,最小公倍数是n。 则有以下结论: a*b=m*n。
如4,6 ----- 最大公约数2,最下公倍数12 满足4*6 = 2*12.
下面通过公式证明:
假设x=abc, y=bcd,
则最小公倍数为abcd, 最大公约数为bc
最小公倍数为abcd=最大公约数为bc*x/bc*y/bc =xy/bc。
也就是说 最小公倍数=两数之积/最大公约数
所以,我们通过求最大公约数就能解决这两个问题了。 下***体分析如何求解最大公约数。
①辗转相除法(又叫欧几里得算法,是一种求两个正整数的最大公约数的古老有效的算法。)
1.输入两整数a和b。2.a%b得余数r
3.如果r=0,则b为两数的最大公约数。
4.如果r≠0,则另a=b,b=r,再从第二步执行。
5.直到r=0,此时b为两数的最大公约数。
#include <stdio.h> #include <stdlib.h> void main() { int a, b, r; scanf("%d%d",&a,&b); r = a % b; while (r!=0) { a = b; b = r; r = a%b; } printf("%d",b); }例如,求15,25的最大公约数。
15除25余15------- 25除15余10--------15除10余5-----------10除5余0. 故最大公约数为5.
②更相减损术(我国古代数学专著《九章算术》中介绍的一种求两个最大公约数的算法)
有两整数a和b:1. 若a>b,则a=a-b
2. 若a<b,则b=b-a
3. 若a=b,则a(或b)即为两数的最大公约数
4. 若a≠b,则再回去执行①
5. 直到a=b。此时a即为两数的最大公约数
#include<stdio.h> void main ( ) { int a,b; scanf("%d%d",&a,&b); while (a!=b) { if(a>b) a-=b; else b-=a; } printf("%d",a); }
求98,63的最大公约数:
98-63=35
63-35=28
35-28=7
28-7=21
21-7=14
14-7=7
所以,98和63的最大公约数等于7。
③穷举法
1. 首先对数据m和n判断大小,小的赋值给smaller,大的赋值给larger2. index索引从2开始到smaller遍历,发现有没有数据可以同时被两者整除,有则更新数据
3. 循环结束后,获取最大的公约数
int GetMaxCommonDivide(int n, int m) { int index; int smaller; int larger; int value; assert(n && m); if(n > m){ larger = n; smaller = m; }else{ larger = m; smaller = n; } value = 1; for(index = 2; index <= smaller; index++){ if(0 == (smaller % index) && 0 == (larger % index)) value = index; } return value; }比如4,6
首先 smaller=4,larger=6。 index=2, smaller%index==0 并且 larger%index==0, 故最大公约数为index=2.
到此,常见的,较好的3种算法都已经介绍好了。在实际应用中,我们的选择,还是视情况而定。下面做个小小的比较。
更相减损术和辗转相除法的主要区别在于前者所使用的运算是“减”,后者是“除”。从算法思想上看,两者并没有本质上的区别,但是在计算过程中,如果遇到一个数很大,另一个数比较小的情况,可能要进行很多次减法才能达到一次除法的效果,从而使得算法的时间复杂度退化为O(N),其中N是原先的两个数中较大的一个。相比之下,辗转相除法的时间复杂度稳定于O(logN)。
算法一说,各有各的好处,各有各的使用对象。希望,在充分掌握这三种方法的基础上,加以选择。
下面补充一个多数最大公约数的算法。 原理类似,利用辗转相除法。
#include <stdio.h> #include <stdlib.h> void main() { int a, b, i, r, n; scanf("%d",&n); // 数的个数 scanf("%d",&b); for (i=0;i<n-1;i++) { scanf("%d",&a); r = a % b; while (r!=0) { a = b; b = r; r = a%b; } } printf("%d",b); }
今天就先写到这里。 希望,对你,对我自己,都能有所帮助。
如有错误,欢迎指正。
相关文章推荐
- 最大公约数&最小公倍数探讨
- 1、最大公约数&最小公倍数探讨
- 数论之最大公约数和最小公倍数
- 常用算法之最大公约数与最小公倍数
- 最小公约数和最大公倍数
- 求n个数的最大公倍数和最小公约数模板
- 求出所有的正整数对 使他们最大公约数为n,最小公倍数为m
- 最小公约数和最大公倍数模板
- 求出全部的正整数对 使他们最大公约数为n,最小公倍数为m
- 常用算法之最大公约数与最小公倍数
- 辗转法求最小公约数和最大公倍数
- c++实验七-最大公倍数和最小公约数
- java学习--求最小公约数和最大公倍数
- 求最小公约数和最大公倍数
- 最大公约数&最小公倍数算法
- c语言求最小公约数和最大公倍数
- 转:最大公约数和最小公倍数的算法
- 最小公倍数----最大公约数
- 最大公约数与最小公倍数
- 最小公倍数和最大公约数计算