用欧几里得算法与Stein算法计算最大公约数

题目:求两个数的最大公约数

分析:求最大公约数有两种普遍的方法:欧几里得算法与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;
}

猜你喜欢

转载自blog.csdn.net/cottonrose_orange/article/details/80529731