一.辗转相除法
欧几里德的辗转相除法的执行过程如下:
⑴ 对于已知的两个自然数m和n,假设m>n。
⑵ 计算m除以n,将得到的余数记为r。
⑶ 如果r=0,则n为求得的最大公约数,否则执行下面一步。
⑷ 将n的值保存到m中(m=n),将r的值保存到n中(n=r),重复执行步骤(2)和(3),直到 r=0,便得到最大公约数。
实现代码如下:
/*************************
  作者: 马露露
  编译器: vc6.0
  创建时间: 2017.03.17
  修改时间: 2017.03.17
  描述: 从键盘输入两个整数,输出两个整数的最大公约数。
*************************/  
using namespace std;
/*辗转相除法求最大公约数*/
int gcd(int a,int b)
{
  int m,n,r;
  if(a>b)   //m为较大数,n为较小数
  {
    m=a;
    n=b;
  }
  else
  {
    m=b;
    n=a;
  }
  r=m%n;    //求余数
  while(r!=0) //辗转相除
  {
    m=n;
    n=r;
    r=m%n;
  }
  return n; //返回最大公约数
}
/*主函数*/
int main()
{
  int a,b,c;
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>a>>b;
    c=gcd(a,b);
    cout<<a<<"和"<<b<<"的最大公约数是:"<<c<<endl;
    cout<<"继续请输入1,结束请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}运行结果如下:

二.Stein算法
假设计算a和b两个数的最大公约数,Stein算法的执行过程如下:
⑴首先判断a或b的值,如果a=0,b就是最大公约数;如果b=0,a就是最大公约数。如果a和b均不为0,则执行下一步。
⑵完成A1=a,B1=b,C1=c的赋值。
⑶判断An和Bn是否为偶数,若都是偶数,则使A(n+1)=An/2,B(n+1)=Bn/2,C(n+1)=Cn/2.如果判断An和Bn中包含一个奇数,则执行步骤(4)、(5)或(6)。
⑷若An是偶数,Bn是奇数,则完成A(n+1)=An/2,B(n+1)=Bn,C(n+1)=Cn的赋值。
⑸若Bn是偶数,An是奇数,则完成B(n+1)=Bn/2,A(n+1)=An,C(n+1)=Cn的赋值。
⑹若An和Bn都是奇数,则完成A(n+1)=|An-Bn|,B(n+1)=min(An,Bn),C(n+1)=Cn的赋值。
⑺n累加1,跳转到第(3)步进行下一轮运算。
在上面的执行过程中,反复用到除2和乘2的操作。其实乘2只需要将二进制整数左移一位,而除2只需要将二进制整数右移一位,这样的程序执行效率更高。
实现代码如下:
/*************************
  作者: 马露露
  编译器: vc6.0
  创建时间: 2017.03.17
  修改时间: 2017.03.17
  描述: 从键盘输入两个整数,输出两个整数的最大公约数。
*************************/  
using namespace std;
/*Stein算法*/
int gcd(int a,int b)
{
  int m,n,r;
  if(a>b)   //m为较大数,n为较小数
  {
    m=a;
    n=b;
  }
  else
  {
    m=b;
    n=a;
  }
  if(n==0)  //较小数为0
  {
    return m; //m即为最大公约数
  }
  if(m%2==0 && n%2==0)  //m,n均为偶数
  {
    return 2*gcd(m/2,n/2); 
  }
  else if(m%2==0 && n%2!=0)
  {
    return gcd(m/2,n);
  }
  else if(m%2!=0 && n%2==0)
  {
    return gcd(m,n/2);
  }
  else
  {
    return gcd((m-n),n);
  }
}
/*主函数*/
int main()
{
  int a,b,c;
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>a>>b;
    c=gcd(a,b);
    cout<<a<<"和"<<b<<"的最大公约数是:"<<c<<endl;
    cout<<"继续请输入1,结束请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}运行结果如下:

三.相减法
相减法求最大公约数的思路如下:
⑴对于已知的两个自然数a和b,如果a>b,则a=a-b;如果b>a,则b=b-a。
⑵判断a和b是否相等,如果不相等,则继续从步骤(1)开始执行;如果相等,则结束循环,输出最大公约数。
实现代码如下:
/*************************
  作者: 马露露
  编译器: vc6.0
  创建时间: 2017.03.17
  修改时间: 2017.03.17
  描述: 从键盘输入两个整数,输出两个整数的最大公约数。
*************************/  
using namespace std;
/*相减法求最大公约数*/
int gcd(int a,int b)
{
  while(a!=b)
  {
    if(a>b)
      a=a-b;
    else
      b=b-a;
  }
  return a;
}
/*主函数*/
int main()
{
  int a,b,c;
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>a>>b;
    c=gcd(a,b);
    cout<<a<<"和"<<b<<"的最大公约数是:"<<c<<endl;
    cout<<"继续请输入1,结束请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}运行结果如下:

四.穷举法
穷举法求最大公约数的思路如下: ⑴对于已知的两个自然数a和b,假设a>b,则穷举的范围是1到b。
⑵当分别用a和b除以r时都能整除,余数为0的那个r就是最大公约数。
实现代码如下:
/*************************
  作者: 马露露
  编译器: vc6.0
  创建时间: 2017.03.17
  修改时间: 2017.03.17
  描述: 从键盘输入两个整数,输出两个整数的最大公约数。
*************************/  
using namespace std;
/*穷举法*/
int gcd(int m,int n)
{
  int r=1;
  int p=0;
  if(m>n)
  {
    r=m;
    m=n;
    n=r;
  }
  while(r<=m)
  {
    if(((m%r)==0) && ((n%r)==0))
      p=r;
    r++;
  }
  return p;
}
/*主函数*/
int main()
{
  int a,b,c;
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>a>>b;
    c=gcd(a,b);
    cout<<a<<"和"<<b<<"的最大公约数是:"<<c<<endl;
    cout<<"继续请输入1,结束请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}运行结果如下:
五.程序整合
/*************************
  作者: 马露露
  编译器: vc6.0
  创建时间: 2017.03.17
  修改时间: 2017.03.17
  描述: 从键盘输入两个整数,输出两个整数的最大公约数。
*************************/  
using namespace std;
int select=1;//select为是否退出系统的标记
/*辗转相除法*/
int gcd1(int m,int n)
{
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>m>>n;
    int r;
    r=m%n;    //求余数
    while(r!=0) //辗转相除
    {
      m=n;
      n=r;
      r=m%n;
    }
    cout<<"最大公约数是:"<<n<<endl;
    cout<<"继续请输入1,返回上一级请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}
/*Stein算法*/
int gcd2(int a,int b)
{
  int m,n;
  if(a>b)   //m为较大数,n为较小数
  {
    m=a;
    n=b;
  }
  else
  {
    m=b;
    n=a;
  }
  if(n==0)  //较小数为0
  {
    return m; //m即为最大公约数
  }
  if(m%2==0 && n%2==0)  //m,n均为偶数
  {
    return 2*gcd2(m/2,n/2); 
  }
  else if(m%2==0 && n%2!=0)
  {
    return gcd2(m/2,n);
  }
  else if(m%2!=0 && n%2==0)
  {
    return gcd2(m,n/2);
  }
  else
  {
    return gcd2((m-n),n);
  }
}
/*相减法*/
int gcd3(int m,int n)
{
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>m>>n;
    while(m!=n)
    {
      if(m>n)
        m=m-n;
      else
        n=n-m;
    }
    cout<<"最大公约数是:"<<m<<endl;
    cout<<"继续请输入1,结束请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}
/*穷举法*/
int gcd4(int m,int n)
{
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>m>>n;
    int r=1;
    int p=0;
    if(m>n)
    {
      r=m;
      m=n;
      n=r;
    }
    while(r<=m)
    {
      if(((m%r)==0) && ((n%r)==0))
        p=r;
      r++;
    }
    cout<<"最大公约数是:"<<p<<endl;
    cout<<"继续请输入1,结束请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}
/*显示Stein算法所求结果*/
int output()
{
  int a,b,c;
  int choose=1;
  while(choose)
  {
    cout<<"输入两个正整数(空格隔开):"<<endl;
    cin>>a>>b;
    c=gcd2(a,b);
    cout<<"最大公约数是:"<<c<<endl;
    cout<<"继续请输入1,结束请输入0"<<endl;
    cin>>choose;
  }
  return 0;
}
/*主菜单*/
int menu()
{  
  int item,m,n;
  cout<<endl; 
  cout<<"************************"<<endl;
  cout<<"*     1.辗转相除法     *"<<endl;
  cout<<"*     2.Stein算法      *"<<endl;
  cout<<"*     3.相减法         *"<<endl;
  cout<<"*     4.穷举法         *"<<endl;
  cout<<"*     5.退出           *"<<endl;
  cout<<"************************"<<endl;
  cout<<endl;
  cout<<"请选择您需要的操作序号(1-4)按回车确认:"<<endl; 
  cin>>item;
  switch(item)
  {
    case 1:
      system("cls");
      gcd1(m,n);
      break; 
    case 2:
      system("cls");
      output();
      break;
    case 3:
      system("cls");
      gcd3(m,n);
      break;
    case 4:
      system("cls");
      gcd4(m,n);
      break;
    case 5:
      select=0;
      break;
    default:
      printf("请在1-5之间选择\n");
  }
  return 0;
}
/*主函数*/
int main()
{
  while(select)
  {
    menu();
  }
  system("pause");
  return 0;
}









