题目:求两个数的最大公约数
分析:求最大公约数有两种普遍的方法:欧几里得算法与Stein算法。
欧几里得算法:
欧几里得算法即辗转相除法,它的方法是用较大的数去除以较小的数,上面的较小的数字和所得的余数构成新的一对数,接着继续用较大的数除以较小的数,继续上面的步骤,直到出现能够整除的两个数,其中较小的数(即被除数)就是要求的最大公约数。以求288和123的最大公约数为例,操作如下:
288÷123=2余42
123÷42=2余39
42÷39=1余3
39÷3=13
所以3就是288和123的最大公约数。
欧几里得算法是计算公约数的传统算法,但它有个致命的缺陷,就是在处理一个很大的素数时,过程不但复杂,还消耗了CPU很多时间。
欧几里得算法代码如下:
#include<stdio.h>
int main()
{
int a;
int b;
int i = 0;
printf("请输入a和b:\n");
scanf("%d %d",&a,&b);
printf("两个数的最大公约数是:\n");
if(a>b)
{
i = a % b;
while(i)
{
a = b;
b = i;
i = a % b;
}
printf("%d",b);
}
else
{
i = b % a;
while(i)
{
b = a;
a = i;
i = b % a;
}
printf("%d",a);
}
return 0;
}
Stein算法:
Stein算法是在欧几里得算法的基础上改进的,与欧几里得算法不同的是,Stein算法中只有整数的移位和加减法。
方法如下:
int k=1;
int i;
int j;
1、首先判断执行以下程序的条件是 i、j 两个数都不为0;
2、如果 i=j,那么最大公约数是i 或 j;
3、如果 i 和 j 都是偶数,i=i/2 ; j=j/2 ; k=k*2 ;(注意:除以2相当于右移,乘2相当于左移);
4、如果 i 是偶数,j 不是偶数,i=i/2 ;
5、
如果 j 是偶数,i 不是偶数,j=j/2 ;
6、如果 i 和 j 都不是偶数,int i1= i ;int j1= j ; i =
ads( i - j ); j = min( i1 , j1 );
7、返回1。
Stein算法代码如下:
#include<stdio.h>
#include<math.h>
int min(int m,int n)
{
if(m<n)
{
return m;
}
else
{
return n;
}
}
int com_div(int i,int j)
{
int min(int m,int n);
int k=1;
while( i!=0 && j!=0 )
{
if( (i%2==0) && (j%2==0))
{
i = i >> 1;
j = j >> 1;
k = k << 1;
}
else if( (i%2==0) && (j%2!=0) )
{
i = i >>1;
}
else if( (i%2!=0) && (j%2==0) )
{
j = j >> 1;
}
else if( (i%2!=0) && (j%2!=0) )
{
int i1 = i;
int j1 = j;
i = abs(i-j);
j = min(i1,j1);
}
}
return k*j;
}
int main()
{
int com_div(int i,int j);
int a;
int b;
printf("请输入a和b:\n");
scanf("%d %d",&a,&b);
printf("两个数的最大公约数是:%d\n",com_div(a,b));
return 0;
}