利用最大公约数的常用算法,求多组数据的最大公约数并显示寻找所花费的时间。
1.辗转相除法(函数嵌套调用)
2.穷举法
3.更相减损法
4.Stein算法
计时函数:
clock_t begin, end;//计数器
begin = clock();//开始计时
end = clock();//计时结束
cost1= (double)(end - begin) / CLOCKS_PER_SEC;
源程序:
#include <iostream>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int divisor (int a,int b) /*辗转相除法*/
{
int temp;
if(a<b) /*通过比较求出两个数中的最大值和最小值*/
{ temp=a;a=b;b=temp;} /*设置中间变量进行两数交换*/
while(b!=0) /*通过循环求两数的余数,直到余数为0*/
{
temp=a%b;
a=b;
b=temp;
}
return (a);/*返回最大公约数到调用函数处*/
}
int qiongjv (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 gcd(int m,int n)/*更相减损法*/
{
int i=0,temp,x;
while(m%2==0 && n%2==0) /*判断m和n能被多少个2整除*/
{
m/=2;
n/=2;
i++;
}
if(m<n) /*m保存大的值*/
{
temp=m;
m=n;
n=temp;
}
while(x)
{
x=m-n;/*求两数之差x*/
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;/*最大公约数为2^i*n*/
}
int Stein(int u,int v)/*Stein算法*/
{
if (u == 0) return v;
if (v == 0) return u;
if (~u & 1)
{
if (v & 1)
return gcd(u >> 1, v);
else
return gcd(u >> 1, v >> 1) << 1;
}
if (~v & 1)
return gcd(u, v >> 1);
if (u > v)
return gcd((u - v) >> 1, v);
return gcd((v - u) >> 1, u);
}
void main()
{
int a[50000];
int i,t1,L;
srand((unsigned)time(NULL));/*设置时间种子,每次输出不同随机数*/
cout<<"-----辗转相除法-----"<<endl;
cout<<"-------穷举法-------"<<endl;
cout<<"-----更相减损法-----"<<endl;
cout<<"-------Stein法------"<<endl;
cout<<"请输入随机产生多少个数据:"<<endl;
cin>>L;
if(L%2!=0||L<=0)/*当输入数据个数为奇数或0时,无法得出全部最大公约数*/
{
cout<<"输入数据不合理"<<endl;
}
else
{
for(i=0;i<L;i++)/*随即输出L个随机数*/
{
a[i]=rand()%100;
}
{
double cost1,cost2,cost3,cost4;
{ cout<<"辗转相除法的最大公约数为:"<<endl;
clock_t begin, end;//计数器
begin = clock();//开始计时
for(i=0;i<(L/2);i++)/*将随机数据的个数分为两两一组*/
{
t1=divisor(a[2*i],a[2*i+1]);/*调用函数获得L/2个最大公约数*/
cout<<t1<<"\t";
}
end = clock();//计时结束
cost1= (double)(end - begin) / CLOCKS_PER_SEC;
}
{ cout<<"穷举法的最大公约数为:"<<endl;
clock_t begin, end;//计数器
begin = clock();//开始计时
for(i=0;i<(L/2);i++)
{
t1=qiongjv(a[2*i],a[2*i+1]);
cout<<t1<<"\t";
}
end = clock();//计时结束
cost2= (double)(end - begin) / CLOCKS_PER_SEC;
}
{ cout<<"更减相损法的最大公约数为:"<<endl;
clock_t begin, end;//计数器
begin = clock();//开始计时
for(i=0;i<(L/2);i++)
{
t1=gcd(a[2*i],a[2*i+1]);
cout<<t1<<"\t";
}
end = clock();//计时结束
cost3= (double)(end - begin) / CLOCKS_PER_SEC;
}
{ cout<<"Stein法的最大公约数为:"<<endl;
clock_t begin, end;//计数器
begin = clock();//开始计时
for(i=0;i<(L/2);i++)
{
t1=Stein(a[2*i],a[2*i+1]);
cout<<t1<<"\t";
}
end = clock();//计时结束
cost4= (double)(end - begin) / CLOCKS_PER_SEC;
}
cout<<"辗转相除法寻找最大公约数时间为:"<<cost1<<endl;
cout<<"穷举法寻找最大公约数时间为:"<<cost2<<endl;
cout<<"更减相损法寻找最大公约数时间为:"<<cost3<<endl;
cout<<"Stein法寻找最大公约数时间为:"<<cost4<<endl;
}
}
}
调试及测试
输入数据为500,5000,10000时
2.穷举法