生活随笔
收集整理的這篇文章主要介紹了
求两个数的最大公约数(C++)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
求兩個數的最大公約數(C++)
一.算法構造
1.輾轉相除法
設兩數為a,b設其中a 做被除數,b做除數,temp為余數
①大數放a中、小數放b中;
②求a/b的余數;temp=a%b
③、若temp=0則b為最大公約數;
④、如果temp!=0則把b的值給a、temp的值給b;
⑤、返回第二步;
流程圖
2.枚舉法
設兩個數為a,b
①比較兩個數的大小
②. 把較小的數從大到小列舉
③在2過程中找到可以同時被a,b整除的數,則這個數為最大公約數
流程圖
3.更相減損法
①.:任意給定兩個正整數;判斷它們是否都是偶數。若是,則用2約簡;若不是則執行第二步。
②:以較大的數減較小的數,接著把所得的差與較小的數比較,并以大數減小數。繼續這個操作,直到所得的減數和差相等為止。
③.第一步中約掉的若干個2與第二步中等數的乘積就是所求的最大公約數。
流程圖
4.Stein算法
整體上就是把整數化小對兩個正整數 x>y :
①均為偶數 gcd( x,y ) =2gcd( x/2,y/2 );
② 均為奇數 gcd( x,y ) = gcd( (x+y)/2,(x-y)/2 );
③.x奇y偶 gcd( x,y ) = gcd( x,y/2 );
④.x偶y奇 gcd( x,y ) = gcd( x/2,y ) 或 gcd( x,y )=gcd( y,x/2 );
流程圖
二.源代碼
#include<iostream>
#include<ctime>
#include<cmath>
using namespace std;
//輾轉相除法
int gcd1(int a,int b)
{int temp;if(a==0||b==0)return 0;if(a<b) { temp=a;a=b;b=temp;} //求最小值最大值,大的用a表示,小的用b表示while(b!=0) //用循環求最大公約數{temp=a%b;a=b; b=temp;}return a; //返回最大公約數
}
//枚舉法
int gcd2(int a,int b)
{int temp; temp=(a>b)?b:a; //求兩數中的最小數while(temp>0) //最小數自減,直到可以同時被a,b整除{if (a%temp==0&&b%temp==0) break; temp--; }return temp; //返回最大公約數
}
//更相減損法
int gcd3(int a,int b)
{int i=0,temp,x;if(a==0||b==0)return 0;if(a==b)return a;while(a%2==0&&b%2==0)//a,b可以被2整除的情況{a/=2;b/=2;i+=1; //計算被2整除的次數}if(a<b) //求兩數的最大值最小值,a存大值,b存小值{temp=a;a=b;b=temp;}while(x){x=a-b;a=(b>x)?b:x;b=(b<x)?b:x;if(b==(a-b))break;}if(i==0)return b;elsereturn(int)pow(2,i)*b;//用<cmath>庫的pow()函數求2^i,返回最大公約數}
//Stein算法
int gcd4(unsigned int x,unsigned int y)
{ int factor=0;int temp;if(x<y){temp=x;x=y;y=temp;} if(0==y){return 0;}while(x!=y){ //當x時偶數時 if(x&0x1){if(y&0x1){ //當x和y都是偶數時 y=(x-y)>>1;x-=y;}else{ //當x是偶數,y是奇數 y>>=1;//移位運算} }else{ //當x是奇數 if(y&0x1){x>>=1;if(x<y){temp=x;x=y;y=temp;}}else { //當x和y都是奇數 x>>=1;y>>=1;++factor; }} }return (x<<factor);}
int main()
{int a,b,c,i,j;double dur;int row;int col=2;
//用動態數組來實現行的輸入cout<<"輸入二維數組的行(列默認為2):";cin>>row;int **p2 ;p2 = new int*[row] ;for(i=0;i<row;i++)p2[i]=new int[col] ;//輸入二維數組的值for(i=0;i<row;i++)for(j=0;j<col;j++)p2[i][j]=rand()%20;//會生成偽隨機數,每次隨機出現的數都一樣,適合本實驗的時間比較
//輸出隨機生成的二維數組cout<<"輸出二位數組:"<<endl;for( i=0;i<row;i++){for(j=0;j<col;j++)cout<<p2[i][j]<<' ' ;cout<<endl;}
//界面設置cout<<"###############選擇輾轉相除法,請輸入0################"<<endl;cout<<"###############選擇窮舉法,請輸入1####################"<<endl;cout<<"###############選擇更相減損法,請輸入2################"<<endl;cout<<"###############選擇stein算法,請輸入3#################"<<endl;cout<<"請輸入你想選擇的方法:";cin>>c;if(c<0||c>4){cout<<"輸入正確的數"<<endl;exit(0);}clock_t start,end;start=clock();for(int k=0;k<row;k++){//cout<<"請輸入兩個整數:";//cin>>a>>b;switch(c){case 0: cout<<"最大公約數為:"<<gcd1(p2[k][0],p2[k][1])<<endl;break;case 1: cout<<"最大公約數為:"<<gcd2(p2[k][0],p2[k][1])<<endl;break;case 2: cout<<"最大公約數為:"<<gcd3(p2[k][0],p2[k][1])<<endl;break;case 3: cout<<"最大公約數為:"<<gcd4(p2[k][0],p2[k][1])<<endl;break;}}end=clock();dur=(double)(end-start);cout<<"時間為:"<<(dur/CLOCKS_PER_SEC)<<"s"<<endl;for(i=0;i<row;i++)delete []p2[i] ;delete []p2 ;
}
三.運行結果
四.實驗總結
這次實驗讓我掌握了很多知識,了解了四種求最大公約數的方法,尤其最后一種算法,對我講比較難理解,花費了很長時間來理解代碼的含義。在寫代碼的時候也遇到了各種各樣的問題,第一個是計時函數的應用,因為之前也沒有了解過語言的各種函數用法,做起來也比較吃力,也在網上,書上找了很多關于計時函數的用法,但是在實際過程中還是有很多錯誤,出現各種問題,時間輸不出來,或者為負數等。第二個是要輸入20組或50組數來比較四種方法的可行性,用隨機數生成函數來實現,rand()函數生成的隨機數都是偽隨機數,方便了這次測試。還使用動態數組來自己輸入二維數組行的大小,更方便一些。第三:這次實驗也提高了一點我的編程能力,分析問題的能力,邏輯思維能力,除了這些還要認真閱讀題目,理解題目,這次把20組數的測試想成了求20個數的最大公約數,在正確的道路上越來越遠。第四:這次編程也讓我知道我的編程能力很差,不知道的知識還很多,還是要多看書,多查資料。代碼中出現的pow()函數,也是第一次了解,以后也要多了解一些常用的庫函數。
五.流程圖
枚舉法
更相減損法
stein算法
總結
以上是生活随笔為你收集整理的求两个数的最大公约数(C++)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。