博客更新

最大公约数的算法优劣性比较

1. 题目分析
本次实验主要内容是运行最大公约数的常用算法,比较得出各个算法的优劣性。
① 应该确定应该用同一组数据比较各个算法的优劣性。
②为使最终结果具有说服力应该使用多组数据进行比较,所以程序要满足数据组数可以改变,以及所输入的数据应该具有随机性。
③数据存储结构选择二维数组,便于操作。(数组最大容量可以改变)
用二维数组s[size][2]存储数据,size的值是可以在程序中改变#define size 1024
④决定各个算法优劣性的因素是算法运行时间,程序中应该加入运行时间函clock();
计算程序运行时间模板:
srand((unsigned)time(NULL)); start=clock();long e=10000000 while(e–);
end=clock();totaltime=((double)(end-start)/CLOCKS_PER_SEC);
⑤由于产生数据具有随机性,所以应该进行异常处理。比如输入数据组数超过我设定的数组容量。
⑥计算数据最大公约数的算法有1.函数嵌套法2.穷举法3.更相减损法4.stein法
**2.算法实现

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define size 1024
int first(int a,int b)//辗转相除法(函数嵌套调用)
{int temp;//设置一个中间量将大的数放在a中,小的数放在b中。
if(a<b)
{temp=a;
a=b;
b=temp;}
while(b!=0)//通过循环求两数余数,知道余数为0
{temp=a%b;
a=b;//变量数值交换,把数值较大的b放到a中,余数放到b中
b=temp;}
return a;}
int second(int a,int b)//穷举法
{int i;//设置中间变量
if(a>b)//求出两数中最小值
i=b;
else
i=a;
while(i>0)
{if(a%i==0&&b%i==0)//只要找到一个i满足可以被a和b同时整除,就停止循环。
return i;
else
i--;}
}
int third(int a,int b)
{int x,y,count=0,temp;
while(a%2==0&&b%2==0)//判断a,b 能被多少个2整除
{a/=2;
b/=2;
count++;
}
if(a<b)//把较大值放在a中,把较小值放在b中
{temp=b;
b=a;
a=temp;}
while(x)
{x=a-b;
if(x<b)
{a=b;//交换值,把较大值放在a中
b=x;}
else
a=x;
if(b==(a-b))//如果减数b和差x相等,停止循环
break;
}
if(count==0)
return b;
else
return ((int)pow(2,count)*b);
}
int forth(int a,int b)//stein法求最大公约数
{int factor=0;
int temp;
if(a<b)//将大数放在a中,小的数放在b中
{temp=a;
a=b;
b=temp;}
if(0==b)//如果b等于0,则二者最大公约数为0
return 0;
while(a!=b)
{
	if(a&0x1)//当a是奇数时
	{
		if(b&0x1)//当a和b都是奇数时
		{
			b=(a-b)>>1;//a-b的值除以2 
			a-=b;}
		else
			b>>=1;//b除以2再次赋给b
	}
	else
	{ if(b&0x1)//当b是奇数时
	{
		a>>=1;//a除以2再赋值给a
		if(a<b)
		{temp=a;
		a=b;
		b=temp;
	}}
	else 
	{a>>=1;
	b>>=1;
	++factor;}
	}
}
return (a<<factor);}
int main()
{int a,b,sign,max,k;
int n;//数据组数
clock_t start,end;
double totaltime;
int tag=1;        //异常处理标识
int s[size][2];
while(tag)
{
	printf("请输入进行最大公约数计算的组数");
	scanf("%d",&n);
	if(n>size)
		printf("输入错误!超出数组容量请重新输入\n");
	else tag=0;
}
srand((unsigned)time(NULL));
for(int i=0;i<n;i++)//使用for循环将rand()产生的任意数放到数组中 
{
	for(int j=0;j<2;j++)
	{
		s[i][j]=rand()%100+1;
		printf("%d\t",s[i][j]);
	}
	printf("\n");
}
while(sign)//sign=0时将退出运算
{
	printf("请进行方法选择\n");
	printf("输入0为退出该功能\n");
	printf("输入1为函数嵌套法\n");
	printf("输入2为穷举法\n");
	printf("输入3为更相减损法\n");
	printf("输入4为stein法\n");
	scanf("%d",&sign);
	start=clock();//运行开始时间
	for(k=0;k<n;k++)
	{a=s[k][0];
	b=s[k][1];
	switch(sign)
	{case 1:
	   max=first(a,b);
	   break;
	case 2:
		max=second(a,b);
		break;
	case 3:
		max=third(a,b);
		break;
	case 4:max=forth(a,b);
		break;
	case 0:
		break;
	}
	if(sign)
		printf("%d和%d的最大公约数为%d\n",s[k][0],s[k][1],max);
	}
	long e=10000000L;
	while(e--);
	end=clock();//运行结束时间
	totaltime=((double)(end-start)/CLOCKS_PER_SEC);//总运行时间
	if(sign!=0)
		printf("此程序的运行时间为:%f秒\n",totaltime);
}
return 0;
}

3.调试、测试及运行结果(至少比较4种GCD算法在给定不同规模测试数据的情况下的平均运行时间)

## ①运行结果

(1)5组数据进行最大公约数求解。
图①:随机产生的5组数据及其功能选择界面。
在这里插入图片描述

图②:函数嵌套法求最大公约数运行时间和结果。
在这里插入图片描述

图③:穷举法求最大公约数运行时间和结果。
在这里插入图片描述

图④:更相减损法求最大公约数运行时间和结果。
在这里插入图片描述

图⑤:stein法求最大公约数结果和运行时间。
在这里插入图片描述

分析:5组数据进行最大公约数求解,函数嵌套法所用时间最短,穷举法所用时间最长,更相减损法和stein 法运行时间相同 。
2)15组数据进行最大公约数求解。
图①:随机产生的15组数据及其功能选择界面。
在这里插入图片描述

图②:函数嵌套法求最大公约数运行时间和结果。
在这里插入图片描述

图③:穷举法求最大公约数运行时间和结果。
在这里插入图片描述

图④:更相减损法求最大公约数运行时间和结果。
在这里插入图片描述

图⑤:stein法求最大公约数结果和运行时间。
在这里插入图片描述

分析:用15组数据进行最大公约数求解,stein法运行时间最快,其次是函数嵌套法,更相减损法,最后是穷举法。
3)25组数据进行最大公约数求解。
图①:随机产生的25组数据及其功能选择界面。
在这里插入图片描述

图②:函数嵌套法求最大公约数运行时间和结果。
在这里插入图片描述

图③:穷举法求最大公约数运行时间和结果。
在这里插入图片描述

图④:更相减损法求最大公约数运行时间和结果。
在这里插入图片描述

图⑤:stein法求最大公约数结果和运行时间。
在这里插入图片描述

分析:用25组数据进行最大公约数求解,函数嵌套法运行时间最快,其次是穷举法,stein法,最后是更相减损法。
②测试截图
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

③调试截图
在这里插入图片描述

④异常处理截图
在这里插入图片描述

4.经验归纳
1)实验结论:用多组数据进行最大公约数求解最好用函数嵌套法.
2)个人心得
本次实验主要内容是运行最大公约数的常用算法,比较得出各个算法的优劣性。
在编写程序中出现的问题有①数据存储结构的选择:刚开始我选择的存储结构是两个一维数组,其缺点是操作繁琐,不便于后面函数的调用数据。最后我选择了二维数组存储数据s[size][2],size的值使用宏定义#define size 1024,缺点是size大小只能通过在程序中进行改变,所以我在后面加入了异常处理,如果输入的数据组数超过了size的值,则输出输入非法重新输入数组组数。②应该重点注意应该用同一组数据计算每个算法的运行时间,进而比较各个算法的优劣性。起初,输入数据只能选择其中一个算法进行运算,我设置了一个switch选择结构,(选0为退出,选1为函数嵌套法,选择2为穷举法,选择3为更相减损法,4为stein法)每当一种算法运算完毕,会在其后输出他的运行时间。③运算程序运行时间函数运用错误。查阅资料得到时间函数运用模板srand((unsigned)time(NULL)); start=clock();longe=10000000L; while(e–);end=clock(); totaltime=((double)(end-start)/CLOCKS_PER_SEC);需要注意的是应该讲开始时间放在算法选择的switch之前。④对算法stein不熟悉,经过查阅资料已经理解清楚了。程序还有不足之处,今后将继续完善优化。

猜你喜欢

转载自blog.csdn.net/weixin_43920565/article/details/88319571