求两数的最大公约数算法
最大公约数,也称最大公因数、最大公因子,指两个或多个整数共有约数中最大的一个;
a,b的最大公约数记为(a,b),同样的,a,b,c的最大公约数记为(a,b,c),多个整数的最大公约数也有同样的记号;
求最大公约数有多种方法,常见的有质因数分解法、短除法、欧几里得算法(又称辗转相除法)、更相减损法。
资料来源:百度百科-最大公约数 链接
质因数分解法&短除法较依赖计算者,灵活性也很大,步骤不固定,本文作者仅使用Java代码实现欧几里得算法(又称辗转相除法)&更相减损法,具体如下:
一、欧几里得算法(又称辗转相除法)
package algorithm.maxCommonDivisor;/*** 求两个数的最大公约数* 欧几里得算法(又称辗转相除法)** @author XUQIANG_DUAN* @date 2019/7/29* @time 9:21*/
public class EuclideanAlgorithm {/*** 辗转相除法** @param a* @param b* @return 最大公约数*/private static int euclidMethod(int a, int b) {/*** 大值&小值*/int maxI = a > b ? a : b;int minI = a > b ? b : a;/*** 余数*/int remainder = maxI % minI;
// System.out.println("余数为:" + remainder);/*** 余数为零,小值为最大公约数* 余数为一,一为最大公约数* 大值&小值的最大公约数与小值与余数的最大公约数相同*/if (remainder == 0) {return minI;} else if (remainder == 1) {return remainder;} else {return euclidMethod(minI, remainder);}}/*** 运行时间&结果记录* currentTimeMillis 为毫秒时间戳* nanoTime 为纳秒时间戳* 1 秒 = 10^3 毫秒* 1 秒 = 10^9 纳秒** @param a* @param b*/private static void timeConsume(int a, int b) {// long start = System.currentTimeMillis();long nstart = System.nanoTime();System.out.println("(" + a + ", " + b + ") | result = " + euclidMethod(a, b));
// long end = System.currentTimeMillis();long nend = System.nanoTime();
// System.out.println("共耗时(单位:ms):" + (end - start) + " | 结束点:" + end + " | 开始点:" + start);System.out.println("共耗时(单位:ns):" + (nend - nstart) + " | 结束点:" + nend + " | 开始点:" + nstart);}public static void main(String[] args) {timeConsume(55, 55);timeConsume(66, 55);timeConsume(10000, 10001);timeConsume(10000, 10003);timeConsume(1350, 1266);timeConsume(1000000, 1000003);}
}
代码运行结果如下:
...(55, 55) | result = 55
共耗时(单位:ns):438614 | 结束点:89819135569674 | 开始点:89819135131060
(66, 55) | result = 11
共耗时(单位:ns):21049 | 结束点:89819135643629 | 开始点:89819135622580
(10000, 10001) | result = 1
共耗时(单位:ns):17636 | 结束点:89819135685727 | 开始点:89819135668091
(10000, 10003) | result = 1
共耗时(单位:ns):23325 | 结束点:89819135732376 | 开始点:89819135709051
(1350, 1266) | result = 6
共耗时(单位:ns):31858 | 结束点:89819135789265 | 开始点:89819135757407
(1000000, 1000003) | result = 1
共耗时(单位:ns):27876 | 结束点:89819135849567 | 开始点:89819135821691Process finished with exit code 0
二、更相减损法
package algorithm.maxCommonDivisor;/*** 求两个数的最大公约数* 更相减损法** @author XUQIANG_DUAN* @date 2019/7/29* @time 10:24*/
public class Subtraction {private static int subMethon(int a, int b) {int result = 1;/*** 大值&小值*/int maxI = a > b ? a : b;int minI = a > b ? b : a;/*** 大值&小值都为偶数,先简约*/while (maxI % 2 == 0 && minI % 2 == 0) {result *= 2;maxI /= 2;minI /= 2;}/*** 差值*/int sub = maxI - minI;
// System.out.println("差值为:" + sub + " | 大值为:" + maxI + " | 小值为:" + minI + " | 结果为:" + result);if (sub == 0) {result *= minI;} else if (sub == 1) {result *= 1;} else {result *= subMethon(minI, sub);}return result;}/*** 运行时间&结果记录* currentTimeMillis 为毫秒时间戳* nanoTime 为纳秒时间戳* 1 秒 = 10^3 毫秒* 1 秒 = 10^9 纳秒** @param a* @param b*/private static void timeConsume(int a, int b) {// long start = System.currentTimeMillis();long nstart = System.nanoTime();System.out.println("(" + a + ", " + b + ") | result = " + subMethon(a, b));
// long end = System.currentTimeMillis();long nend = System.nanoTime();
// System.out.println("共耗时(单位:ms):" + (end - start) + " | 结束点:" + end + " | 开始点:" + start);System.out.println("共耗时(单位:ns):" + (nend - nstart) + " | 结束点:" + nend + " | 开始点:" + nstart);}public static void main(String[] args) {timeConsume(5,55);timeConsume(66,55);timeConsume(10000,10001);timeConsume(10000,10003);timeConsume(1350, 1266);timeConsume(1000000, 1000003);}
}
代码运行如下:
...
(5, 55) | result = 5
共耗时(单位:ns):445440 | 结束点:90158027966585 | 开始点:90158027521145
(66, 55) | result = 11
共耗时(单位:ns):43235 | 结束点:90158028074105 | 开始点:90158028030870
(10000, 10001) | result = 1
共耗时(单位:ns):31289 | 结束点:90158028144648 | 开始点:90158028113359
(10000, 10003) | result = 1
共耗时(单位:ns):753209 | 结束点:90158028942799 | 开始点:90158028189590
(1350, 1266) | result = 6
共耗时(单位:ns):39253 | 结束点:90158029022443 | 开始点:90158028983190
Exception in thread "main" java.lang.StackOverflowError 【栈内存溢出异常】
at algorithm.maxCommonDivisor.Subtraction.subMethon(Subtraction.java:40)...
Disconnected from the target VM, address: '127.0.0.1:54677', transport: 'socket'
Process finished with exit code 1
结束语
更相减损法较辗转相除法时间&空间复杂度都较高,也极易发生栈内存溢出异常,原因也不难理解,乘除为加减的高级运算同时效率也倍增。
求两数的最大公约数算法相关推荐
- 两数的最大公约数算法基础及优化
最大公约数算法 师从 辗转相除法(欧几里得算法) 时间复杂度 更相减损术(<九章算术>) 时间复杂度 二分化更相减损术 思路 优化 时间复杂度 师从 本篇是观Vita君算法视频后总结,他是 ...
- 嵌入式 ARM 汇编编程例题(二维数组按规律求和,求两数 gcd / lcm,求数组 min / max,字符串复制,排序)
文章目录 0x00. 整数加减乘除 0x01. 一维数组按某种规律求和 0x01.1 求 1~100 之和 0x01.2. 求一维数组的和 0x01.2. 求一维数组的所有奇数的和 0x02. 二维数 ...
- 一个数里有那些约数用c++怎么做_两数的最大公约数你会求吗?(内附完整算法代码)...
两个数的最大公约数怎么求? 思考题目的同时,我在这也顺便发出三个灵魂疑问? 什么又是更相减损法? 什么又是辗转相除法? 什么又是欧几里得算法? 不懂没关系,往下看 要解决两数的最大公约数问题?,你首先 ...
- python求两数最大公因数_Python求两个数的最大公约数
Python求两个数的最大公约数 一.求最大公约数算法: 1. 整数A对整数B进行取整, 余数用整数C来表示 举例: C = A % B 2. 如果C等于0,则C就是整数A和整数B的最大公约数 3. ...
- 【C语言】实现求两个数的最大公约数【四种算法】
题目 给定两个数,求这两个数的最大公约数 例如: 输入:20 40 输出:20 解题思路 最大公约数:即两个数据中公共约数的最大者 求解的方式比较多,暴力穷举.辗转相除法.更相减损法.Stein算法算 ...
- C语言实现辗转相除法和更相减损法求两数最大公约数,及求最小公倍数的方法
在学习从C语言过程中,我们会遇到一个题目,求两个整数的最大公约数,那么接下来分别介绍两种方法求最大公约数 1,辗转相除法 辗转相除法, 又名欧几里德算法(Euclidean Algorithm),是求 ...
- C:求两个数的最大公约数详解(硬核算法,辗转相除法,更相减损法)
最大公因数,也称最大公约数.最大公因子. 定义: 指两个或多个整数共有约数中最大的一个. a,b的最大公约数 记为(a,b),同样的,a,b,c的最大公约数记为(a,b,c),多个整数的最大公约数也有 ...
- 求两数最大公约数,最小公倍数-Java
两数的最大公约数的计算是有数学规律的,程序只是按照规律辅助计算,其中包括了递归和循环两种实现.而最小公约数可由(m*n)/ (最大公约数)得到.具体代码如下: package test;import ...
- 程序员数学基础【四、取模应用-判断奇偶数、判断素数、求两个数的最大公约数、水仙花数】(Python版本)
测试使用语言:[Python] 由于此类语言入门非常容易,哪怕初中生亦可以,并且本科/研究生写论文.做实验多数所用语言都是[Python]故而选择此语言. 代码运行平台:[win10 x64] 代码环 ...
最新文章
- vc中GetDlgItem用法
- linux 访问windows共享
- epoll或者kqueue的原理是什么?
- laravel log 对象_swoole运行模式加速laravel应用的详细介绍(life)
- 线性表--算法设计题2.25
- cdoj 1092 韩爷的梦
- 防止sql拼接的Java方法_JAVA程序防止SQL注入的方法
- Axure8.0激活码
- 长视频鏖战15年后 爱奇艺这份财报窥见“新蓝海“
- Excel 字符串拆分
- 史上最新最全面的java大数据学习路线(新手小白必看版本)
- #二、股价和时间转换(江恩箱)
- Java Poi 根据文字内容 插入 word 图片
- android测试内存的软件下载,华为p10内存测试软件(androbench) v5.0.1 免费版
- 解决ftp 出现Passive mode refused的办法
- 入行多年软件测试总结的经验
- BAT包围下的企业协作与通信之道
- thinkphp(2)
- d21包,d21库,d21类 Python
- ASP.NETt运行原理和运行机制