標籤:style blog io os sp on 2014 log 代碼
功能:求a和b的最大公約數
傳入參數:整數a、整數b
傳出參數:a和b的最大公約數
演算法1:歐幾裡得演算法
時間複雜度:O(n)
實現原理:
設兩數為a、b(a>b),求a和b最大公約數(a,b)的步驟如下:
用b除a,得a÷b=q......r1(0≤r1)。若r1=0,則(a,b)=b;
若r1≠0,則再用r1除b,得b÷r1=q......r2 (0≤r2).
若r2=0,則(a,b)=r1,若r2≠0,則繼續用r2除r1,……
如此下去,直到能整除為止。其最後一個非零除數即為(a,b)。
實現代碼:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring> using namespace std;template <typename T>T GCD(T a,T b){ if(a < b) { T temp = a; a = b; b = temp; } if(b == 0) return a; return GCD(b,a%b);}int main(){ int a = 5,b = 6; printf("%d\n",GCD(a,b)); return 0;}
演算法2:stein演算法
時間複雜度:O( log(max(a,b)) )
實現原理:
gcd(a,a)=a,也就是一個數和其自身的公約數仍是其自身。
gcd(ka,kb)=k gcd(a,b),也就是最大公約數運算和倍乘運算可以交換。
特殊地,當k=2時,說明兩個偶數的最大公約數必然能被2整除。
當k與b互為質數,gcd(ka,b)=gcd(a,b),也就是約掉兩個數中只有其中
一個含有的因子不影響最大公約數。特殊地,當k=2時,說明計算一個
偶數和一個奇數的最大公約數時,可以先將偶數除以2。
演算法過程:
1、如果An=Bn,那麼An(或Bn)*Cn是最大公約數,演算法結束
2、如果An=0,Bn是最大公約數,演算法結束
3、如果Bn=0,An是最大公約數,演算法結束
4、設定A1=A、B1=B和C1=1
5、如果An和Bn都是偶數,則An+1=An/2,Bn+1=Bn/2,Cn+1=Cn*2(注意,乘2隻要把整數左移一位即可,除2隻要把整數右移一位即可)
6、如果An是偶數,Bn不是偶數,則An+1=An/2,Bn+1=Bn,Cn+1=Cn(很顯然啦,2不是奇數的約數)
7、如果Bn是偶數,An不是偶數,則Bn+1=Bn/2,An+1=An,Cn+1=Cn(很顯然啦,2不是奇數的約數)
8、如果An和Bn都不是偶數,則An+1=|An-Bn|/2,Bn+1=min(An,Bn),Cn+1=Cn
9、n加1,轉1
實現代碼:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;template <typename T>T GCD(T a,T b){ if (a == 0) return b; if (b == 0) return a; if (~a & 1) { if (b & 1) return GCD(a >> 1, b); else return GCD(a >> 1, b >> 1) << 1; } if (~b & 1) return GCD(a, b >> 1); if (a > b) return GCD((a - b) >> 1, b); return GCD((b - a) >> 1, a);}int main(){int a = 4,b = 6;printf("%d\n",GCD(a,b));return 0;}
求最大公倍數:
實現代碼:
template <typename T>T LCM(T a,T b){return a/GCD(a,b)*b;}
最大公約數、最小公倍數【數論】