辗转相除法(即欧几里德算法)求两个数的最大公约数的步骤如下:
先用小的一个数除大的一个数,得第一个余数;
再用第一个余数除小的一个数,得第二个余数;
又用第二个余数除第一个余数,得第三个余数;
这样逐次用后一个数去除前一个余数,直到余数是0为止。那么,最后一个除数就是所求的最大公约数(如果最后的除数是1,那么原来的两个数是互质数)。
例如求1515和600的最大公约数,
第一次:用600除1515,商2余315;
第二次:用315除600,商1余285;
第三次:用285除315,商1余30;
第四次:用30除285,商9余15;
第五次:用15除30,商2余0。
1515和600的最大公约数是15。
辗转相除法是求两个数的最大公约数的方法。如果求几个数的最大公约数,可以先求两个数的最大公约数,再求这个最大公约数与第三个数的最大公约数。这样依次下去,直到最后一个数为止。最后所得的一个最大公约数,就是所求的几个数的最大公约数。
具体代码:
/*
some test samples
9999999 9452134
9876543 6543214
8765432 7894562
*/
#include <iostream>
#include <math.h>
#include <time.h>
#define SIZE1 10000001
#define SIZE2 1000001
using namespace std;
bool prime[SIZE1];
long f[SIZE2];
long nhave[SIZE2],mhave[SIZE2];
//欧几里德算法以无可争议的时空优势取得了第一名
long Euclid(long m,long n){ //欧几里德解法
long r;
while(n!=0){
r=m%n;
m=n;
n=r;
}
return m;
}
long Force(long m,long n){ //穷举暴力法
long r;
for(r=m<=n?m:n;;r--)
if(m%r==0&&n%r==0)
return r;
}
long GenPrime(long n){ //筛选法求素数
long i,j,k,sq;
sq=(long)sqrt(n);
for(i=2,k=0;i<=n;i++)
if(prime[i]==0){
if(i<=sq)
for(j=i*i;j<=n;j+=i)
prime[j]=1;
f[k++]=i;
}
f[k]=0x7fffffff;
return k;
}
long PrimeGcd(long m,long n){ //素数因子法
long i,j,v,mn,gcd;
mn=m<=n?m:n;
for(i=0;f[i]<=mn;i++)
nhave[i]=mhave[i]=0;
for(i=0;f[i]<=mn;)
if(m%f[i]==0)
mhave[i]++,m/=f[i];
else
i++;
for(i=0;f[i]<=mn;)
if(n%f[i]==0)
nhave[i]++,n/=f[i];
else
i++;
for(i=0,gcd=1;f[i]<mn;i++){
v=nhave[i]<=mhave[i]?nhave[i]:mhave[i];
if(v!=0)
for(j=0;j<v;j++)
gcd*=f[i];
}
return gcd;
}
int main(){
long m,n,gcd,i,mx,all;
clock_t start,finish;
start=clock();
all=GenPrime(SIZE1-1);
finish=clock();
cout<<start<<' '<<finish<<' '<<finish-start<<endl; //筛选法求素数时间
while(cin>>m>>n){
start=clock();
gcd=Euclid(m,n);
finish=clock();
cout<<"Euclid: "<<gcd<<' '<<start<<' '<<finish<<' '<<finish-start<<endl;//最大公约数,算法开始、结束时间,运行时间
start=clock();
gcd=Force(m,n);
finish=clock();
cout<<"Brute force: "<<gcd<<' '<<start<<' '<<finish<<' '<<finish-start<<endl;
start=clock();
gcd=PrimeGcd(m,n);
finish=clock();
cout<<"Middle school procedure: "<<gcd<<' '<<start<<' '<<finish<<' '<<finish-start<<endl;
}
return 0;
}