一、實驗要求
運行最大公約數的常用算法,並進行程序的調試與測試,要求程序設計風格良好,並添加異常處理模塊。
二、實驗方法(四種)
1.輾轉相除法(歐幾里德法) C語言中用於計算兩個正整數a,b的最大公約數,采用函數嵌套調用形式進行求兩個數的最大公約數。其算法過程為:
前提:設兩數為a,b設其中a做被除數,b做除數,temp為余數
Steps:大數放a中,小數放b中;
求a/b的余數;
若temp=0則b為最大公約數;
如果temp!=0則把b的值給a,temp的值給a;
返回第二步。
流程圖:

2、窮舉法(枚舉法)
從兩個數中較小數開始由大到小列舉,直到找到公約數立即中斷列舉,得到的公約數便是最大公約數。
流程圖:

3、更相減損法
Steps:任意給定兩個正整數;判斷它們是否都是偶數。若是,則用2約簡;若不是則執行第二步;
以較大的數減較小的數,接着把所得的差與較小的數比較,並以大數減小數。繼續這個操作,直到所得的減數和差相等為止。
則第一步中約掉的若干個2與第二步中等數的乘積就是所求的最大公約數。
流程圖:

4、Stein算法
性質:gcd(kx,ky)=k*gcd(x,y)
對兩個正整數 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).
流程圖:

三、算法實現
//C語言實現 四種方法求最大公約數 // 2019 03 // WANTING WANG #include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h> //輾轉相除法 int gcd(int a,int b) { if(a%b==0) return b; else; return gcd(b,a%b); } //窮舉法 int divisor (int a, int b) //自定義函數求兩數的最大公約數 { int temp;//定義整型變量 temp=(a>b)?b:a;//采種條件運算表達式求出兩個數中的最小值 while(temp>0) { if(a%temp==0&&b%temp==0)//只要找到一個數能同時被a,b所整除,則中止循環 break; temp--;//如不滿足if條件則變量自減,直到能被a,b所整除 } return (temp);//返回滿足條件的數到主調函數處 } //更相減損法 int gcd2(int m,int n) { int i=0,temp,x; while(m%2==0&&n%2==0)//判斷m和n能被多少個2整除 { m/=2; n/=2; i+=1; } if(m<n)//m保存大的值 { temp=m; m=n; n=temp; } while(x) { x=m-n; m=(n>x)?n:x; n=(n<x)?n:x; if(n==(m-n)) break; } if(i==0) return n; else return (int) pow(2,i)*n; } //Stein算法 int Stein( unsigned int x, unsigned int y ) /* return the greatest common divisor of x and y */ { int factor = 0; int temp; if ( x < y ) { temp = x; x = y; y = temp; } if ( 0 == y ) { return 0; } while ( x != y ) { if ( x & 0x1 ) {/* when x is odd */ if ( y & 0x1 ) {/* when x and y are both odd */ y = ( x - y ) >> 1; x -= y; } else {/* when x is odd and y is even */ y >>= 1; } } else {/* when x is even */ if ( y & 0x1 ) {/* when x is even and y is odd */ x >>= 1; if ( x < y ) { temp = x; x = y; y = temp; } } else {/* when x and y are both even */ x >>= 1; y >>= 1; ++factor; } } } return ( x << factor ); } int main() { int i; int a[30]; for(i=0;i<30;i++) { a[i]=rand()%100 + 1; printf("%d ",a[i]); } printf("\n"); int b[30]; for(i=0;i<30;i++) { b[i]=rand()%100 + 1; printf("%d ",b[i]); } printf("\n"); clock_t start,finish; double dur; start= clock(); for(i=0;i<30;i++) { //printf("輾轉相除法所得最大公約數為:%d\n",gcd(a[i],b[i])); //printf("窮舉法所得最大公約數為:%d\n",divisor(a[i],b[i])); printf("更相減損法所得最大公約數為:%d\n",gcd2(a[i],b[i])); //printf("Stein算法所得最大公約數為:%d\n",Stein(a[i],b[i])); } finish=clock(); dur=(double)(finish-start)/CLOCKS_PER_SEC; printf("運行所用的時間為:%lf s\n",dur); return 0; }
四、測試




