一、 题目分析
实验题目:运行最大公约数的常用算法,并进行程序的调式与测试,要求程序设计风格良好,并添加异常处理模块(如输入非法等)。
分析:运用四种算法分别计算最大公约数,并选择手动输入数据验证算法正确和随机产生大量数据比较算法优劣
二、 算法构造
1)辗转相除法
2)穷举法
3)更相减损法
4)Stein算法
三、 算法实现
#include<stdio.h>
#include <time.h>
//辗转相除法 求最大公约数
int divisor1(int a,int b)
{
int temp;
if(a<b)
{
temp=a;
a=b;
b=temp;
}
while(b!=0)//辗转相除法跳出条件
{
temp=a%b;
a=b;
b=temp;
}
return(a);
}
//穷举法 求最大公约数
int divisor2(int a,int b)
{
int temp;
temp=(a>b)?b:a;
while(temp>0)//直至运行至temp为1
{
if(a%temp==0&&b%temp==0)//当temp为这两个数的最大公约数时跳出
break;
temp--;
}
return(temp);
}
//更相减损法 求最大公约数
int gcd(int a,int b)
{
while(a!=b)
{
if(a>b)
a = a - b;
if(a<b)
b = b - a;
}
return a;
}
//Stein算法 求最大公约数
int stein(int x,int 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%2==1)//x为奇数时
{
if(y%2==1)//且y为奇数时
{
y=(x-y)>>1;
x-=y;
}
else//x为奇数y为偶数时
{
y>>=1;
}
}
else
{
if(y%2==1)//x为偶数y为奇数时
{
x>>=1;
if(x<y)
{
temp=x;
x=y;
y=temp;
}
}
else//xy都为偶数时
{
x>>=1;
y>>=1;
++factor;
}
}
}
return(x<<factor);
}
main()
{
int a=-1,b=-1,x1,x2,x3,x4,x5,x,i,j,m,n,status,input;
clock_t start,finish;
double duration;
char t;
printf("运用各个算法计算最大公约数\n");
printf("请选择输入方式:\n");
printf("1.键盘输入\n2.生成随机数输入\n");
m=getch();
switch(m)
{
case '1':
{
printf("请输入两个整数:\n(ps:请用逗号隔开,直至输入正确)");
for(m=0;;m++)
{
n=0;
input=scanf("%d,%d",&a,&b);
while((t=getchar())!='\n'&& t!=EOF) n++;
if(input==2 && n==0) break;
}
x1=divisor1(a,b);
x2=divisor2(a,b);
x3=gcd(a,b);
x4=stein(a,b);
printf("1.辗转相除法:%d\n2.穷举法:%d\n3.更相减损法:%d\n4.Stein算法:%d\n",x1,x2,x3,x4);
break;
}
case '2':
{
printf("请输入数据的组数:");
scanf("%d",&j);//选择做几次循环
printf("1.辗转相除法 函数嵌套调用:");
start= clock();//开始计数
for(i=0;i<j;i++)
{
a=rand()%1000+rand()%10000;//产生第一个随机数
b=rand()%1000+rand()%10000;//产生第二个随机数
divisor1(a,b);
}
finish=clock();//结束计时
duration=(double)(finish-start)/CLOCKS_PER_SEC;
printf(" 耗时为 %lf us\n",duration);
printf("2.穷举法:");
start= clock();//开始计数
for(i=0;i<j;i++)
{
a=rand()%1000+rand()%10000;//产生第一个随机数
b=rand()%1000+rand()%10000;//产生第二个随机数
divisor2(a,b);
}
finish=clock();//结束计时
duration=(double)(finish-start)/CLOCKS_PER_SEC;
printf(" 耗时为 %lf us\n",duration);
printf("3.更相减损法:");
start= clock();//开始计数
for(i=0;i<j;i++)
{
a=rand()%1000+rand()%10000;//产生第一个随机数
b=rand()%1000+rand()%10000;//产生第二个随机数
gcd(a,b);
}
finish=clock();//结束计时
duration=(double)(finish-start)/CLOCKS_PER_SEC;
printf(" 耗时为 %lf us\n",duration);
printf("4.Stein算法:");
start= clock();//开始计数
for(i=0;i<j;i++)
{
a=rand()%1000+rand()%10000;//产生第一个随机数
b=rand()%1000+rand()%10000;//产生第二个随机数
stein(a,b);
}
finish=clock();//结束计时
duration=(double)(finish-start)/CLOCKS_PER_SEC;
printf(" 耗时为 %lf us\n",duration);
break;
}
}
}
四、 调试、测试及运行结果
1) 测试调试部分
2) 运行部分
五、 经验归纳
1) 学习到了计算最大公约数的4种算法,特别是从stein算法中学习到了退位进位的相关操作
2) 学习了随机数生成与获取程序运行时间的操作
3) 学习了关于异常处理的相关知识并在程序中使用
4) 了解到了scanf函数的返回值与错误输入时对变量的影响