目录

前言

1.暴力枚举法

2.辗转相除法

3.更相减损术

4.更相减损术与移位相结合


前言

几个整数中公有的约数,叫做这几个数的公约数;其中最大的一个,叫做这几个数的最大公约数。例如:12、16的公约数有1、2、4,其中最大的一个是4,4是12与16的最大公约数,一般记为(12,16)=4。12、15、18的最大公约数是3,记为(12,15,18)=3。

1.暴力枚举法

int get_greatest_common_divisorV1(int a, int b) {int big = a>b ? a : b;int small = a<b ? a : b;if (big % small == 0) {return small;}int i = 0;for (i = small / 2; i > 1; i--) {if (small % i == 0 && big % i == 0) {return i;}}return 1;
}

该法思路特别简单,从较小整数的一半开始,试图找到一个合适的整数i,看看这个整数能否被a和b同时整除。虽然这个方法实现了所要求的功能,但是效率十分的低,比如输入的整数是10000和10001,用该法就需要循环10000/2-1=4999次。

该法的时间复杂度是O(min(a,b))。

2.辗转相除法

定理:两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。

例如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数。

int get_greatest_common_divisorV2(int a, int b) {int big = a>b ? a : b;int small = a<b ? a : b;if (big % small == 0) {return small;}return get_greatest_common_divisorV2(big % small, small);
}

该法可以使用递归的方法把问题逐步简化,逐渐把两个较大的整数之间的运算简化为成两个较小的整数之间的运算,直到两个数可以整除,或者其中一个数减小到1为止。不过该法仍有一个问题所在,当两个整数较大时,做a%b取模运算的性能会比较差。

该法的时间复杂度是O(log(max(a,b)))。

3.更相减损术

原理:两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数。

        例如10和25,25减10的差是15,那么10和25的最大公约数,等同于10和15的最大公约数。

int get_greatest_common_divisorV3(int a, int b) {if (a == b) {return a;}int big = a>b ? a : b;int small = a<b ? a : b;return get_greatest_common_divisorV3(big - small, small);
}

逐渐把两个较大的整数之间的运算简化成两个较小整数之间的运算,直到两个数可以相等为止,最大公约数就是最终相等的这两个数的值。但是更相减损术是不稳定的是算法,当两数相差悬殊时,如计算10000和1的最大公约数,就要递归9999次。

该法的时间复杂度为O(max(a,b))。

4.更相减损术与移位相结合

总所周知,移位运算的性能非常好。

int get_greatest_common_divisorV4(int a, int b) {if (a == b) {return a;}if ((a&1) == 0 && (b&1) == 0) {return get_greatest_common_divisorV4(a >> 1, b >> 1) << 1;} else if ((a&1) == 0 && (b&1) != 0) {return get_greatest_common_divisorV4(a >> 1, b);} else if ((a&1) != 0 && (b&1) == 0) {return get_greatest_common_divisorV4(a, b >> 1);} else {int big = a>b ? a : b;int small = a<b ? a : b;return get_greatest_common_divisorV4(big - small, small);}
}

(获取最大公约数的方法get_greatest_common_divisor简称为gcd)

当a和b均为偶数的时, gcd(a,b)=2×gcd(a/2,b/2)=2×gcd(a>>1,b>>1)。

当a为偶数,b为奇数时,gcd(a,b)=gcd(a/2,b)=gcd(a>>1,b)。

当a为奇数,b为偶数时,gcd(a,b)=gcd(a,b/2)=gcd(a,b>>1)。

当a和b均为奇数时,可以先利用更相减损术运算一次,gcd(a,b)=gcd(b,a-b),此时a-b必然是偶数,然后又可以继续进行移位运算。

例如计算10和25的最大公约数的步骤如下:

  1. 整数10通过移位,可以转化成5和25的最大公约数。
  2. 利用更相减损术,计算出25-20=20,转化成求5和20的最大公约数。
  3. 整数20通过移位,可以转换为求5和10的最大公约数。
  4. 整数10通过移位,可以转化成求5和5的最大公约数。
  5. 利用更相减损术,因为两数相等,所以最大公约数是5。

这种方式在两数较小时可能看不出计算次数的优势,但当两数越大时,计算次数的减少就会越明显。

该法的时间复杂度为O(log(max(a,b)))。

参考书籍《漫画算法:小灰的算法之旅》

如何求出两个整数的最大公约数相关推荐

  1. c语言学习-利用函数指针的方法,求任意给出两个整数的x和y的和、差。

    编写一个程序,利用函数指针的方法,求任意给出两个整数的x和y的和.差. 程序流程图: 代码: #include<stdio.h> void main() {int x,y,*m=& ...

  2. 分别求两个整数的最大公约数和最小公倍数。_看不懂辗转相除法求最小公约数?以身相许那种哦!...

    给你打个比喻吧:你英雄救美了,美女想要报答你,你想要1000块感谢费,但是美女却想要以身相许 ,懂了吧,同样都是报答,只是用了不一样的方式,辗转相除法也是这样,你两个数的最大公约数不容易求,我就用另外 ...

  3. 写两个函数 分别求两个整数的最大公约数和最小公倍数 用主函数调用这两个函数 并输出结果 两个整数由键盘输入

    写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果.两个整数由键盘输入. 思路:先写一个主函数,通过主函数调用子函数来分别求出最大公倍数和最小公约数. 代码如下: ...

  4. 设计求任意两个整数和的web程序,用户通过提交页面(input.jsp)输入两个整数,并提交给一个(sum.jsp)程序

    张继军 董卫 <java web 应用开发技术与实案列教程>课后习题之第三章第4题 题解 题目内容 源代码 input.jsp sum.jsp positive.jsp negetive. ...

  5. PTA 7-2 求两个整数的最大公约数和最小公倍数

    求两个整数的最大公约数和最小公倍数 .定义一个函数求最大公约数,定义另一个函数根据求出的最大公约数求最小公倍数.在主函数中输出最大公约数和最小公倍数 . 输入格式: 在主函数一行中给出2个整数A和B. ...

  6. 写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入。

    题目:写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果.两个整数由键盘输入. 先来看看运行结果吧! 根据题目要求我们先来编写主函数部分.输入两个整数,定义子函数, ...

  7. C语言设计函数求最大公约数,C语言程序设计课程设计--编写函数求取两个整数m,n的最大公约数和最小公倍数.doc_在线文库www.lddoc.cn...

    C语言程序设计课程设计--编写函数,求取两个整数m,n的最大公约数和最小公倍数.doc C语言程序设计课程设计C语言程序设计课程设计评语考勤(10)纪律(10)过程(40)设计报告(30)答辩(10) ...

  8. ACMNO.22 C语言-公约公倍2 写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果两个整数由键盘输入。 输入 两个数 输出 最大公约数 最小公倍数

    题目描述 写两个函数,分别求两个整数的最大公约数和最小公倍数, 用主函数调用这两个函数,并输出结果两个整数由键盘输入. 输入 两个数 输出 最大公约数 最小公倍数 样例输入 6 15 样例输出 3 3 ...

  9. ACMNO.7 输入两个正整数m和n,求其最大公约数和最小公倍数。 输入 两个整数 输出 最大公约数,最小公倍数 样例输入 5 7 样例输出 1 35

    题目描述 输入两个正整数m和n,求其最大公约数和最小公倍数. 输入 两个整数 输出 最大公约数,最小公倍数 样例输入 5 7 样例输出 1 35 来源/分类 C语言 示例照片: 设计思路: 本题最难的 ...

最新文章

  1. Rust linux 系统接口使用
  2. elment上传pdf文件至服务器,基于element-ui组件手动实现单选和上传功能.pdf
  3. Codeforces757E.Bash Plays With Functions(积性函数 DP)
  4. java中InputStream和OutputStream的使用场景
  5. LeetCode--Search in Rotated Sorted Array
  6. C++数据结构之链式结构
  7. mvcpager之学习
  8. eclipse tomcat新建一个_Javaweb07-Eclipse自动创建动态web项目
  9. Linux C编程---指针数组简析(二维数组、多级指针)
  10. 高性能缓存服务器Varnish架构配置
  11. mysql privileges
  12. Tomcat,Jboss,Weblogic通过jndi连接数据库
  13. git的简单使用(windows)
  14. 人工神经网络的算法原理,人工智能神经网络算法
  15. Linux下手动安装screen
  16. 对ResNet的理解
  17. 企二代继承者们如何再续辉煌
  18. python read( )函数
  19. HCIA(华为体系初级网络安全工程师)eNSP(基础实验二RIP实验)
  20. JPA错误 -- No identifier specified for entity: com.fyh.meng.configsystem.domain.GemConfig

热门文章

  1. 百度贴吧测试部门实习生电话面试
  2. 在Adobe Acrobat Pro DC中为什么注释会莫名其妙消失怎么办
  3. 自由到底意味着什么(三)个人商业模式
  4. SeleniumLibrary4.5.0 关键字详解(五)
  5. 在vue中使用flexible响应式布局——默认html字体大小(font-size)是54px的问题
  6. 阅读文献:MHCSeqNet:a deep neural networkmodel for universal MHC binding prediction
  7. Redis——Windows安装
  8. 海洋环境科学概论知识整理--2
  9. go pear.php 下载,请注意!有人攻破了PEAR网站并篡改了go-pear.phar安装包
  10. linux day1