求一個數的最大公約數的三種思路——解題筆記
求一個數的最大公約數的三種思路——解題筆記
程式設計之美上的題目:求一個數的最大公約數。
這道題目有三種解題思路,總結如下:
思路一:
直接使用輾轉相除法,這個不多介紹,程式碼如下:
// 直接輾轉相除法
int gcd1(int a, int b)
{
for(int m = a%b; m != 0; m = a%b)
{
a = b;
b = m;
}
return b;
}
分析:輾轉相除法需要用到數值之間的取餘運算,這是非常耗時間的。
思路二:
改進輾轉相除法中取餘(除法)運算,改為減法。這裡可以利用一個規律,x和y的最大公約數等於x-y和y的最大公約數。不過需要判斷x和y的大小。
程式碼如下:
// x和y的最大公約數等於x-y和y的最大公約數
int gcd2(int a, int b)
{
if(a < b)
swap(a, b); // 預設前面的數較大
while(b)
return gcd2(b, a-b); // 遞迴
return a;
}
分析:雖然這種方法只有減運算,用的是遞迴的實現形式。但是,需要遞迴的次數比較多,假如a和b之間相差較大,那麼每次都只是相減,會迭代很多次。
思路三:
可以結合前面兩個思路的優點,我們不全都是用減運算,偶爾用一次除法,不過只是除以2,即判斷奇偶數,而且用移位運算實現。
程式碼如下:
// 通過判斷奇偶數,減少迭代次數
bool isEven(int a)
{
return !(a & 1); // 按位與來判斷奇偶數
}
int gcd3(int a, int b)
{
if(a < b)
swap(a, b); // 預設前面的數較大
if(!b)
return a;
if(isEven(a)) // if a is even
{
if(isEven(b)) // b is even at the same time
return (gcd3(a>>1, b>>1) <<1); // note that *2
else
return (gcd3(a>>1, b)); // if only a is even
}
else
{
if(isEven(b))
return gcd3(a, b>>1); // is only b is even
else
return gcd3(a-b, b); // neither a or nor b is even
}
}
分析:時間複雜度只是a和b中較大數的二進位制位數,也就是O(log max(a, b))。注意其中判斷是否為奇偶數用的是位運算。
相關文章
- 求最大公約數 & 最大公約數
- 求最大公約數 最簡手寫加STL
- 面試官:來寫個程式碼求一下兩個數的最大公約數吧面試
- 演算法設計與分析:求兩個自然數的最大公約數演算法
- 求兩個正整數的最大公約數與最小公倍數--C#實現C#
- 求最大公約數(輾轉相除法)
- 求最大公公約數(最大公因數)—— 歐幾里得演算法演算法
- 更相減損法(求最大公約數)
- 【數學問題】最大公約數與最小公倍數
- C++ 一種交換兩個數的思路C++
- 求三個數的最小公倍數
- 004 最大公約數
- 最大公約數,最小公倍數
- 最小公倍數&&最大公約數
- 連求最大公約數都不會,我怕不是上了個假大學
- NumPy 差分、最小公倍數、最大公約數、三角函式詳解函式
- 約瑟夫環(約瑟夫問題)求最後出列的人數
- C. 最大公約數
- 更相減損法求最大公約數(Greatest Common Divisor)
- 6-8 使用函式求最大公約數 (10分)函式
- 最大公約數和最小公倍數
- 最小公倍數和最大公約數
- 記一個有趣的數學題
- [SDOI2015]約數個數和-[BZOJ4176]Lucas的數論-題解
- 用遞迴求出最大公約數和最小公倍數,求補充最小公倍數的遞迴用法遞迴
- 【JAVA習題六】輸入兩個正整數m和n,求其最大公約數Java
- C語言 用更相減損術求最大公約數,最小公倍數C語言
- 【考研數學】大家喜歡這種用不同顏色標記解題思路的方式嘛?
- 輾轉相除法與更相減損術(求最大公約數)
- 關於一個最簡單的數獨解題實現與疑惑一
- python語言程式設計——求最大公約數和最小公倍數演算法Python程式設計演算法
- C++:最小公倍數與最大公約數C++
- 演算法第四版-找兩個數的最大公約數演算法演算法
- 一個小小的演算法題:求兩數之和演算法
- 怎樣解題|題7.5.12:因數的個數
- 用一個巨集實現求兩個數中的最大數
- acwing246 區間最大公約數
- Python求10個數的平均數實戰案例講解!Python
- Python求一個數的平方根Python