GCD算法
GCD(get Greatest Common Divisor)獲得最大公約數(shù)的方法。
輾轉(zhuǎn)相除法
輾轉(zhuǎn)相除法, 又名歐幾里得算法,該算法的目的是求出兩個(gè)正整數(shù)的最大公約數(shù)。它是已知最古老的算法, 其產(chǎn)生時(shí)間可追溯至公元前 300 年前。
定理:兩個(gè)正整數(shù) a 和 b (a>b),它們的最大公約數(shù)等于a除以 b的余數(shù) c 和 b 之間的最大公約數(shù)。
例如:求10 和 25的最大公約數(shù),可以先求25除以10商2余5,那么10和25的最大公約數(shù),等同于10和5的最大公約數(shù),依次類(lèi)推。
代碼實(shí)現(xiàn):
//迭代,輾轉(zhuǎn)相除法 public static int gcd(int a, int b) {//判斷a和b誰(shuí)大if (a < b) {a ^= b;b ^= a;a ^= b;}int sum = a % b;while (sum != 0) {a = b;b = sum;sum = a % b;}return b; }//遞歸,輾轉(zhuǎn)相除法 public static int gcd2(int a, int b) {if (a < b) {a ^= b;b ^= a;a ^= b;}if (a % b == 0) {return b;}return gcd2(b, a % b); }更相減損術(shù)
更相減損術(shù)也是一種求最大公約數(shù)的算法。
原理:兩個(gè)正整數(shù)a和b(a>b),它們的最大公約數(shù)等于 a-b 的減值c和較小數(shù)b的最大公約數(shù)。
例如:求10 和 25的最大公約數(shù),可以先求25減10的差是15,那么10和25的最大公約數(shù),等同于10和15的差,依次類(lèi)推。
代碼實(shí)現(xiàn):
//迭代,更相減損術(shù) public static int gcd3(int a, int b) {if (a < b) {a ^= b;b ^= a;a ^= b;}int sum = a - b;while (sum != 0) {a = b;b = sum;sum = a - b;}return b; }//遞歸,更相減損術(shù) public static int gcd4(int a, int b) {if (a < b) {a ^= b;b ^= a;a ^= b;}if (a - b == 0) {return b;}return gcd4(b, a - b); }位運(yùn)算優(yōu)化
a和b的4種情況分析:
例如:求10和25的最大公約數(shù)步驟如下。
- 整數(shù)10通過(guò)移位,可以轉(zhuǎn)換成求5和25的最大公約數(shù)。
 - 利用更相減損術(shù),計(jì)算出25?5=20,轉(zhuǎn)換成求5和20的最大公約數(shù)。
 - 整數(shù) 20通過(guò)移位,可以轉(zhuǎn)換成求5和10的最大公約數(shù)。
 - 整數(shù) 10通過(guò)移位,可以轉(zhuǎn)換成求5和5的最大公約數(shù)。
 - 利用更相減損術(shù),因?yàn)閮蓴?shù)相等,所以最大公約數(shù)是 5。
 
代碼實(shí)現(xiàn):
public static int gcd5(int a, int b) {//a,b相等直接返回if (a == b) {return b;}//四種情況if ((a & 1) == 0 && (b & 1) == 0) {// a,b都為偶數(shù)return gcd5(a >>> 1, b >>> 1) << 1;// 等價(jià)于 gcd5(a/2,b/2)*2} else if ((a & 1) == 0 && (b & 1) == 1) {// a為偶數(shù),b為奇數(shù)return gcd5(a >>> 1, b);} else if ((a & 1) == 1 && (b & 1) == 0) {// a為奇數(shù),b為偶數(shù)return gcd5(a, b >>> 1);} else {//都為奇數(shù)//進(jìn)行一次更相減損術(shù),求絕對(duì)值return gcd5(b, Math.abs(a - b));} }時(shí)間復(fù)雜度分析
- 暴力枚舉法:時(shí)間復(fù)雜度是 O(min(a,b))。
 - 輾轉(zhuǎn)相除法:時(shí)間復(fù)雜度不太好計(jì)算,可以近似為 O(log(max(a,b))),但是取模運(yùn)算性能較差。
 - 更相減損術(shù):避免了取模運(yùn)算,但是算法性能不穩(wěn)定,最壞時(shí)間復(fù)雜度為 O(max(a,b))。
 - 更相減損術(shù)與移位相結(jié)合:不但避免了取模運(yùn)算,而且算法性能穩(wěn)定,時(shí)間復(fù)雜度為 O(log(max(a,b)))。
 
總結(jié)
                            
                        - 上一篇: 数列求和推导
 - 下一篇: 建立主DNS区域和辅助DNS区域的最佳实