一、题目分析
实验题目:运行最大公约数的常用算法,并进行程序的调式与测试,要求程序设计风格良好,并添加异常处理模块(如输入非法等)。
分析:运用四种算法分别计算最大公约数,并选择手动输入数据验证算法正确和产生20组数据比较算法优劣
二、算法构造
1,辗转相除法
2,穷举法
3,更相减损法
4,Stein算法
三,算法实现
#include<iostream>
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
class Number
{
private:
int num1;
int num2;
public:
void set();
bool judge();
void zhanzhuan();//辗转相除法
void Qiongqu();//穷举法
void Genxiang();//更相减损法
void Stein();
int Stein(int a,int b);//Stein法
};
void Number::set()//输入函数
{
cin>>num1>>num2;
}
bool Number::judge()//判断输入的值是否正确
{
bool flag;
if(num1>0&&num2>0)
flag=false;
else
flag=true;
if(flag)
{
cout<<"数据输入错误,请重新输入:"<<endl;
cin>>num1>>num2;
}
return flag;
}
void Number::zhanzhuan()
{
int a=num1;
int b=num2;
int t1,temp;
if(a<b) //求出最大值和最小值
{
temp=a;
a=b;
b=temp;
}
do //通过循环求两束的余数,直到余数为0
{
t1=a%b;
a=b; //变量数值交换
b=t1;
}while(t1!=0);
cout<<"这两个数的最大公约数为:"<<a<<endl;
}
void Number::Qiongqu()
{
int a=num1;
int b=num2;
int temp,t1;
temp=(a>b)?b:a; //求出最小值
while(temp>0)
{
if(a%temp==0&&b%temp==0) break;//只要找到一个数能同时被a,b整除,则停止循环
temp--;
}
t1=temp;
cout<<"这两个数的最大公约数为:"<<t1<<endl;
}
void Number::Genxiang()
{
int a=num1;
int b=num2;
int i=0,temp,x;
while(a%2==0&&b%2==0) //判断a,b能被多少个2整除
{
a=a/2;
b=b/2;
i=i+1;
}
if(a<b) //a保存最大值
{
temp=a;
a=b;
b=temp;
}
while(x)
{
x=a-b; //较大的值减去较小的值,接着吧所得的差与较小的数比较,并以大数减小数。
a=(b>x)?b:x;
b=(b<x)?b:x;
if(b==a) //值到所得的减数和差相等
break;
}
if(i==0)
cout<<"这两个数的最大公约数为:"<<b<<endl;
else
cout<<"这两个数的最大公约数为:"<<pow(2,i)*b<<endl;
}
int Number::Stein(int a,int b)
{
if (a < b)//将a,b中将的数给a,小的给b
{
int temp=0;
temp=a;
a=b;
b=temp;
}
if (b == 0) return a;
if((a&0x1)==0&&(b&0x1)==0) return 2*Stein(a>>1,b>>1); //两数都是偶数
if((a&0x1)==0&&(b&0x1)!=0) return Stein(a>>1,b); //一偶一奇
if((a&0x1)!=0&&(b&0x1)==0) return Stein(a,b>>1); //一奇一偶
if((a&0x1)!=0&&(b&0x1)!=0) return Stein((a-b)>>1,b);//两数都是奇数
}
void Number::Stein()
{
int x,y,z;
x=num1;
y=num2;
z=Stein(x,y);
cout<<z<<endl;
}
int main()
{
clock_t start, finish; //时间函数
int x,y;
bool isFalse=true;
Number n;
{
cout<<"请输入两个整数"<<endl;
n.set();
while(isFalse)
{
isFalse=n.judge ();
}
cout<<"辗转相除法:"<<endl;
start=clock();n.zhanzhuan();finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
cout<<"穷举法:"<<endl;
start=clock();n.Qiongqu(); finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
cout<<"更相减损法:"<<endl;
start=clock();n.Genxiang();finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
cout<<"Stein法:"<<endl;
start=clock();n.Stein();finish=clock();cout<<"time:"<<((double)(finish-start)/1000)<<endl;
return 0;
}
}
四,调试,测试及运行结果
a.测试调试
20组数据:
以上方法依次测试数据
1.
2,
3,
4,
b。运行结果
五、总结
1,学习到了计算最大公约数的四种方法,辗转相除法容易理解但运算繁杂,易错,该算法运算时间长等不足,更相减损法和辗转相除法相比算法更精炼,更相减损法避免了求余运算,但两数相差过大时,递归次数会非常多,影响算法性能
2.通过对异常的处理,学习到自己没掌握的知识。
3,Stein算法只有整数的移位和加减法。
4,学会了对时间函数的应用