求两数的最大公约数算法
最大公約數,也稱最大公因數、最大公因子,指兩個或多個整數共有約數中最大的一個;
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 | 開始點:89819135821691
Process 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 【棧內存溢出異?!?br /> ?? ?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
結束語
更相減損法較輾轉相除法時間&空間復雜度都較高,也極易發生棧內存溢出異常,原因也不難理解,乘除為加減的高級運算同時效率也倍增。
?
?
總結
以上是生活随笔為你收集整理的求两数的最大公约数算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dmz和端口映射_使用DMZ主机功能代替
- 下一篇: [NOTE in progress] S