1. 程式人生 > 實用技巧 >最大公約數及最小公倍數

最大公約數及最小公倍數

最小公倍數 = 兩數之積 / 最大公約數,因此只要得出最大公約數,便可得出最小公倍數,下面將通過幾種演算法進行實現

1.輾轉相除法(又稱歐幾里德演算法)

  • 較大的數 % 較小的數 = 第一餘數

  • 較小的數 % 第一餘數 = 第二餘數

  • 第一餘數 % 第二餘數 = 第三餘數

  • ······

直到結果為0

程式碼如下:

#include "stdio.h"
int main(){
    int num1, num2;
    int temp;
    int temp1, temp2;
    printf("輸入兩個數:");
    scanf_s("%d,%d",&num1, &num2);
    temp1 = num1;
    temp2 = num2;
    if(temp1 < temp2){//確保temp1為輸入的兩個數中,數值大的那個
        temp = temp1;
        temp1 = temp2;
        temp2 = temp;
    }
    /*********************************************/
    while(temp1 % temp2){
        temp = temp2;
        temp2 = temp1 % temp2;
        temp1 = temp;
    }
    /********************************************/
    printf("最大公約數:%d\n", temp2);
    printf("最小公倍數:%d\n", num1*num2 / temp2);
}

執行結果如下:

2.更相減損法

  • 判斷兩數是否是偶數,若是,則用2約簡,否則執行下一步,約簡到兩者都不是偶數時,執行下一步

  • 較大的數 - 較小的數 = 第一差

  • 以較大的數減較小的數,接著把所得的差與較小的數比較,並以大數減小數。繼續這個操作,直到所得的減數和差相等為止。

  • 最後相等的值乘上2的冪(約簡2的次數)即得最大公約數

程式碼如下:

    /*********************************************/
    while(temp1 != temp2){
        if(temp1 > temp2)
            temp1 -= temp2;
        else
            temp2 -= temp1;
    }
    /*********************************************/

執行結果同上

3.Stein演算法

由於對於兩個數x y,若有x>y,則必有:

  • x,y均為偶數 \(gcd(x,y)=2gcd(\frac{x}{2},\frac{y}{2})\)

  • x,y均為奇數 \(gcd(x,y)=gcd(\frac{x+y}{2},\frac{x-y}{2})\)

  • x為奇y為偶 \(gcd(x,y)=gcd(x,\frac{y}{2})\)

  • x為偶y為奇 \(gcd(x,y)=gcd(\frac{x}{2},y)\)

故只要將x,y依據上式換算成偶數,偶數換算成奇數後再次依據上式換算成新的偶數,每換算成一次偶數,記數加1,直到兩個數最後相等,將相等的值乘上2的冪(計數值)即得最大公約數,

上式中的數並不一定必須是2,也可換成其他的任意的數,只不過2是最小的素數,此處便用了2

程式碼如下:

int  Stein(int num1,int num2)
{
    int power = 0;
    int temp;
    if (num2 == 0)
        return 0;
    while (num1 != num2){
        if (num1 & 0x1){//when num1 is odd
            if (num2 & 0x1){//when num1 and num2 are both odd
                num1 = (num1 + num2) >> 1;//num1 = (num1 + num2)/2
                num2 = num1  - num2;//num2 = (num1 - num2)/2
            }
            else//when num1 is odd and num2 is even
                num2 >>= 1;
        }
        else{//when num1 is even
            if (num2 & 0x1){//when num1 and num2 are both even
                num1 >>= 1;
                if (num1 < num2){//ensure that num1 is greater than num2
                    temp = num1;
                    num1 = num2;
                    num2 = temp;
                }
            }
            else{//when num1 is even and num2 is odd
                num1 >>= 1;//num1 = mum1/2
                num2 >>= 1;//num2 = num2/2
                power++;
            }
        }
    }
    return (num1 << power);//gcd = num1 * 2^power
}
/*********************************************/
    temp2 = Stein(temp1,temp2);
/*********************************************/

執行結果同上

stein演算法是在歐幾里德演算法上做的改良,可以快速處理任何大數(超過128位的表示範圍),而歐幾里德演算法遇到大數則需要很多時間(因為位運算和加減運算相較於取餘運算來說,CPU的計算量更少)