#include <iostream>
#include <cmath>
using namespace std;
int gcd_1(int x,int y);
int gcd_2(int x,int y);
int gcd_3(int x,int y);
int Sieve(int n);
int *prime;//存放质数的数组指针
int main()
{
int a=0,b=0;
cin>>a>>b;
cout<<"欧几里德辗转相除法:"<<gcd_1(a,b)<<endl;
cout<<"连续整数检测法 :"<<gcd_2(a,b)<<endl;
cout<<"小学方法 :"<<gcd_3(a,b)<<endl;
/*int s=Sieve(200);
for(int k=0;k<s;k++)
cout<<prime[k]<<" "<<endl;
return 0;*/
}
//函数描述:欧几里德辗转相除法求最大公约数
//参数:两个大于等于0的整数
//返回值:这两个数的最大公约数,若返回-1表示出错
int gcd_1(int x,int y)
{
if(x>=0&&y>=0)
{
return (y==0)?x:gcd_1(y,x%y);
}
else
{
return -1;
}
}
//函数描述:连续整数检测法求最大公约数
//参数:两个大于等于0的整数
//返回值:这两个数的最大公约数,若返回-1表示出错
int gcd_2(int x,int y)
{
if(x>0&&y>0)
{
int t=(x<y)?x:y;
while(t>0)
{
if(x%t==0)
{
if(y%t==0)
{
return t;
}
}
t--;
}
}
else
{
return -1;
}
}
int gcd_3(int x,int y)
{
if(x>0&&y>0)
{
int result=1;//存放最大公约数
int min=(x<y)?x:y;
int num=Sieve(min);
if(num>0)
{
int i=0;//用来标记prime[]的下标
while((i<num)&&(x/prime[i]>=1)&&(y/prime[i]>=1))
{
//如果同时是这两个质数的质因数,那就让result*=prime[i];
if((x%prime[i]==0)&&(y%prime[i]==0))
{
result*=prime[i];
x/=prime[i];
y/=prime[i];
}
else
{
i++;
}
}
}
return result;
}
else
{
return -1;
}
}
//函数描述:计算所有小于等于n的质数,存放在全局的prime[]中
//参数:int类型的数n,为计算的上限
//返回值:所有小于等于n的质数的个数
int Sieve(int n)
{
//全部初始化为0
int *tmp=new int[n+1]();
for(int i=0;i<n+1;i++)
tmp[i]=0;
//我在自己电脑上不用上面的语句也能清零,学校实验室不行,why
//这里出现一个问题:我如果直接传进来常数eg Sieve(200) 可以初始化为全0
//但是如果用一个变量传进来,就不会初始化为全0 why?
//for(int p=0;p<n+1;p++)
// cout<<tmp[p]<<endl;
for(int i=2;i<sqrt(n+1);i++)
{
//没被消去
if(0==tmp[i])
{
int j=i*i;
while(j<=n+1)
{
tmp[j]=1;//1表示消去
j+=i;
}
}
}
//现在所有小于等于n的质数全部存在tmp[]数组中
//如果tmp[i]为0则,i是质数
prime=new int[n+1];
int i=0;
int sum=0;//用来记录质数的个数
for(int j=2;j<=n+1;j++)
{
//如果是质数,则复制到prime中
if(0==tmp[j])
{
sum++;
prime[i++]=j;
}
}
return sum;
}
我的新浪博客地址:http://blog.sina.com.cn/s/blog_64ecfc2f0101atrl.html