【轉】求最大公約數的4種方法


一、實驗要求

運行最大公約數的常用算法,並進行程序的調試與測試,要求程序設計風格良好,並添加異常處理模塊。

二、實驗方法(四種)

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;
 }

 

四、測試



在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM