求最大公因子的簡單(時間複雜度小)演算法
阿新 • • 發佈:2019-01-05
1.輾轉相除法
用(a,b)表示a和b的最大公約數
有定理: 已知a,b,c為正整數,若a除以b餘c,則(a,b)=(b,c)。 (證明過程請參考其它資料)
例如:求gcd(319,377): ∵ 377÷319=1(餘58) ∴gcd(377,319)=gcd(319,58); ∵ 319÷58=5(餘29), ∴ gcd(319,58)=gcd(58,29); ∵ 58÷29=2(餘0), ∴ gcd(58,29)= 29; ∴ gcd(319,377)=29.
演算法實現
#include <iostream> #include <math.h> using namespace std; int gcd1(int a,int b)//遞迴版本 { if (a<b) //確定被除數和除數 { int temp=a; a=b; b=temp; } if (b==0) //求出結果 { return a; } else { <strong>return gcd1(b,a%b); //遞迴呼叫</strong> } } int gcd2(int a,int b)//迴圈版本 { if (a<b) { int temp=a; a=b; b=temp; } while ( b!=0) { int c=a%b; a=b; b=c; } return a; } int main() { int a,b; cout<<"請輸入兩個正數:"<<endl; cin>>a>>b; cout<<a<<"與"<<b<<"的最大公約數是:"<<gcd2(a,b)<<endl;//cout<<a<<"與"<<b<<"的最大公約數是:"<<gcd1(a,b)<<endl;
輾轉相除法的時間複雜度為O(logN)。
存在的問題,當兩個整形數較大時,做a%b的取模運算效能會比較低,所以,還有一個演算法叫更相減損演算法,更相減損術來自與《九章算術》 第一步:任意給定兩個正整數;判斷它們是否都是偶數。若是,則用2約簡;若不是則執行第二步。第二步:以較大的數減較小的數,接著把所得的差與較小的數比較,並以大數減小數。繼續這個操作,直到所得的減數和差相等為止。則第一步中約掉的若干個2與第二步中等數的乘積就是所求的最大公約數。其中所說的“等數”,就是最大公約數。求“等數”的辦法是“更相減損”法例1、用更相減損術求98與63的最大公約數。解:由於63不是偶數,把98和63以大數減小數,並int gcd(int a, int b)
{
while(a != b)
{
if(a > b)
a -= b;
else
b -= a;
}
return a;
}
所以說,採用什麼演算法求兩個數的最大公約數要看這兩個數的值