GCD與LCM

目錄

GCD與LCM

GCD

歐幾里得

 更相減損術

輾轉相除法與更相減損術的比較

GCD的二進制寫法(stein算法)

LCM

分數的lcm


GCD與LCM

GCD

歐幾里得

遞歸寫法


形式1:
int gcd(int a,int b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}
形式2:
int gcd(int x,int y){return y==0?x:GCD(x%y)}

非遞歸寫法

int gcd(int a,int b)
{
    while(b)
    {
        a=a%b;
        swap(a,b);
    }
    return a;
}

 更相減損術

while(!(a%2) && !(b%2))
{
		a = a/2;
		b = b/2;
}
while(a != b)
{
		if(a>b){
			a = a-b;
		}else{
			b = b-a;
		}
}

輾轉相除法與更相減損術的比較

(1)兩者都是求最大公因數的方法,計算上輾轉相除法以除法爲主,更相減損術以減法爲主,計算次數上輾轉相除法計算次數相對較少,特別當兩個數字大小區別較大時計算次數的區別較明顯。

 (2)更相減損術本質是輾轉相除法,輾轉相除法效率比較高

(3)從結果體現形式來看,輾轉相除法體現結果是以相除餘數爲0則得到,而更相減損術則以減數與差相等而得到。

GCD的二進制寫法(stein算法)

二進制寫法先用移位的方式對兩個數除2,直到兩個數不同時爲偶數。然後將剩下的偶數(如果有的話)做同樣的操作,這樣做的原因是如果u和v中u爲偶數,v爲奇數,則有gcd(u,v)=gcd(u/2,v)。到這時,兩個數都是奇數,將兩個數相減(因爲gcd(u,v) = gcd(u-v,v)),得到的是偶數t,對t也移位直到t爲奇數。每次將最大的數用t替換。

Stein算法只有整數的移位和加減法。下面就來說一下Stein算法的原理:

不加證明的給出:

  • 若a和b都是偶數,則記錄下公約數2,然後都除2(即右移1位);
  • 若其中一個數是偶數,則偶數除2,因爲此時2不可能是這兩個數的公約數了
  • 若兩個都是奇數,則a = |a-b|,b = min(a,b),因爲若d是a和b的公約數,那麼d也是|a-b|和min(a,b)的公約數。

遞歸式:

int SteinGCD(int a, int b) {
    if (a < b) { int t = a; a = b; b = t; }
    if (b == 0) return a;
    if ((a & 1) == 0 && (b & 1) == 0)
        return SteinGCD(a >> 1, b >> 1) << 1;
    else if ((a & 1) == 0 && (b & 1) != 0)
        return SteinGCD(a >> 1, b);
    else if ((a & 1) != 0 && (b & 1) == 0)
        return SteinGCD(a, b >> 1);
    else
        return SteinGCD(a - b, b);
}

非遞歸:

int SteinGCD(int a, int b) {
    int acc = 0;
    while ((a & 1) == 0 && (b & 1) == 0) {
        acc++;
        a >>= 1;
        b >>= 1;
    }
    while ((a & 1) == 0) a >>= 1;
    while ((b & 1) == 0) b >>= 1;
    if (a < b) { int t = a; a = b; b = t; }
    while ((a = (a - b) >> 1) != 0) {
        while ((a & 1) == 0) a >>= 1;
        if (a < b) { int t = a; a = b; b = t; }
    }
    return b << acc;
}

LCM

LCM(A,B)=A*B/GCD(A,B)

這樣寫法有可能會錯,因爲a * b可能因爲太大  超出int  或者 超出 long long)

最好寫成LCM(A,B)=A/GCD(A,B)*B;

分數的lcm

公式:lcm(S/a, S/b) = S/gcd(a, b)  例如:S = 9,a = 4,b = 6

發佈了101 篇原創文章 · 獲贊 18 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章