最大公約數 最小公倍數

來源:互聯網
上載者:User

求解最大公約數和最小公倍數。

有兩大種方法:求解最大公約數有歐幾裡德演算法和stein演算法。其中歐幾裡德演算法又分為一般的和擴充的歐幾裡德演算法。

而求解兩數的最小公倍數則利用了它們的最大公約數,有公式lcm(a,b)=a*b/gcd(a,b)。lcm是最小公倍數的英文縮寫,gcd同樣。

所以求解最小公倍數的代碼只在一般歐幾裡德演算法分析中介紹下,讀者可以舉一反三。

 

一、歐幾裡德演算法

1、一般歐幾裡德演算法(只求最大公約數)

求最大公約數一個經典的方法就是輾轉相除法了。以下將要介紹的代碼也是利用其求解的。

其中,求解最大公約數用了遞迴和非遞迴兩種方法,代碼中有注釋。  

 

代碼如下:

#include<iostream>using namespace std;int gcd(int a,int b)  //a,b最大公約數,遞迴 {if(b==0)return a;else    return gcd(b,a%b);}int GCD(int a,int b)   //a,b最大公約數,非遞迴 {    int tem;        if(a<b)    {       tem=a;       a=b;       b=tem;    }        int rem=1;    while(rem!=0)    {        rem=a%b;        a=b;        b=rem;    }        return a;} int lcm(int a,int b)  //最小公倍數 {    return a*b/gcd(a,b);}int main(){    int a,b,lc,gc1,gc2;        cout<<"輸入:";     while(cin>>a>>b)    {       gc1=gcd(a,b);       gc2=GCD(a,b);       lc=lcm(a,b);              cout<<"最大公約數:"<<gc1<<endl;       cout<<"最大公約數:"<<gc2<<endl;       cout<<"最小公倍數:"<<lc<<endl;       cout<<endl;       cout<<"輸入:";     }        return 0;} 

         測試結果:

 再來囉嗦兩句。求解最大公約數的非遞迴方法應該說很好理解,完全的輾轉相除法。而遞迴方法則由於沒有判斷a,b的大小關係,很容易讓人迷惑。

 比如,輸入28   1274時,會有人覺得不能求解。其實,輸入28   1274和輸入1274   28是基本一樣的。解釋如下:輸入28   1274,調用gcd(28,1274),

 b=1274,b!=0,所以執行return  gcd(b,a%b)也即return  gcd(1274,28)。因為28%1274=28!到此,已經和直接輸入1274   28一樣了。

2、擴充歐幾裡德演算法(不僅僅可求出最大公約數,還可解出方程ax+by=gcd(a,b)中的x和y)

其詳細描述及證明,請參考:點擊開啟連結

 

演算法代碼:

int extendGcd(int a,int b,int &x,int &y)   //擴充gcd,可以求出gcd(a,b)以及ax+by=gcd(a,b)中x,y的值{if(b==0){x=1;y=0;return a;}else{int a1=extendGcd(b,a%b,x,y);int tmp=x;x=y;y=tmp-a/b*y;return a1;}}

 

二、Stein演算法

Stein演算法與歐幾裡德演算法的不同是:Stein演算法只有整數的移位與加減法,不需要進行除法和模數運算。

 

演算法描述:

(1)判斷a或b是否為0,若a=0,則b就是最小公倍數;若b=0,則a就是最小公倍數。演算法結束。

(2)設a1=a,b1=b,c1=1。

(3)判斷an、bn是否為偶數

①若都是偶數,則令a(n+1)=an/2,b(n+1)=bn/2,c(n+1)=2*cn。

②若an是偶數,則令a(n+1)=an/2,b(n+1)=bn,c(n+1)=cn。

③若bn是偶數,則令a(n+1)=an,b(n+1)=bn/2,c(n+1)=cn。

④若an、bn都是奇數,則令a(n+1)=|an-bn|,b(n+1)=min(an,bn),c(n+1)=cn。

(4)n累加1,跳轉到(3)進行下一輪計算。

 

演算法代碼如下:

方法一:

int gcd(int a,int b){int min=(a>b)?b:a;int max=(a>b)?a:b;if(min==0)return max;if(max%2==0 && min%2==0)return 2*gcd(max/2,min/2);if(max%2==0)return gcd(max/2,min);if(min%2==0)return gcd(max,min/2);return gcd((max+min)/2,(max-min)/2);  //都是奇數,貌似和演算法給出的不太一樣,我測試了幾組資料都是對的。。。}

方法二:

int gcd(int a,int b){int min=(a>b)?b:a;int max=(a>b)?a:b;if(!min)return max;if(!max)return min;if(!(min&1) && !(max&1))  //都是偶數return gcd(min>>1,max>>1)<<1;if(!(min&1))      //小數為偶return gcd(min>>1,max);if(!(max&1))      //大數為偶return gcd(min,max>>1);//return gcd((max-min)>>1,min);  //都是奇數,不知道為啥這個也行???    return gcd(max-min,min);  //都是奇數}

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.