算法学习十六----求最大公约数

本文介绍了一种改进的辗转相除法求最大公约数的算法,通过避免大整数除法提高效率。该算法利用移位运算替代除法,并根据不同情况采取不同策略减少迭代次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:求最大公约数
用辗转相除法求最大公约数的解法相信大家都很熟悉,就是用大数除以小数,然后取出余数与之前较小的数再递归地进行同样的操作,直到其中一个数为0。
但是这样的除法在遇到大整数的时候作除法非常地耗时,这样对效率方面有很大的影响。
设两个数为x,y
采用辗转相除法的分析,如果一个数能够同时正处x和y,则必能同时整除x-y和y;而能够同时整除x-y和y的数也必能同时整除x和y,即x和y的公约数与x-y与y的公约数是相同的,其最大公约数也是相同的,即f(x,y)=f(x-y,y),那么就可以不再需要进行大整数的取模运算,而转换成简单得多的大整数减法。
但是,如果遇到大整数的时候,要做减法就要进行很多次迭代,所以还有改进的地方。
接下来分析公约数的特点:
对于y和x来说,如果y=k*y1,x=k*x1。那么有f(y,x) = k*f(y1,x1)
如果x=p*x,假设p是素数,并且y%p!=0,那么f(x,y)=f(p*x1,y)=f(x1,y)
我们还知道2是一个素数,而且对于大整数而言,可以很容易地将除以2/乘以2的运算转换成移位运算,从而避免了大整数除法,以下做分析:
p=2
若x,y均为偶数,f(x,y) = 2*f(x/2, y/2) = 2*f(x>>1, y>>1)
若x为偶数,y为奇数,f(x,y) = f(x/2, y) = f(x>>1, y)
若x为奇数,y为偶数,f(x,y)=f(x,y/2)=f(x,y>>1)
若x,y均为奇数,f(x,y)=f(y, x-y),那么x-y就是一个偶数,所以下一步递归一定会有除以2的操作。

算法伪代码:

/*
*count max common divisor
*/
int mcd(int x, int y)
     if x < y
          then return mcd(y, x)
     else if y == 0
          then return x
     if x is even
          if x is even && y is even
          //x >> 1 equals x/2
               then return (mcd(x >> 1, y >> 1) >> 1)
          else return mcd(x >> 1, y)
     if x is not even && y is even
          then return mcd(x, y >> 1)
     else return mcd(y, x-y)



C++实现

int mcd(int x, int y)
{
	//if x < y
	if(x < y)
	{
		//then return mcd(y, x)
		return mcd(y, x);
	}//else if y == 0
	else if(y == 0)
	{
		//then return x
		return x;
	}
	else
	{
		//if x is even
		if(isEven(x))
		{
			//if x is even && y is even
			if(isEven(y))
			{
				//x >> 1 equals x/2
				//return (mcd(x >> 1, y >> 1) >> 1)
				return (mcd(x >> 1, y >> 1) << 1);
			}
			else
			{
				//else return mcd(x >> 1, y)
				return mcd(x >> 1, y);
			}
		}
		else
		{
			//if x is not even && y is even
			if(isEven(y))
			{
				//then return mcd(x, y >> 1)
				return mcd(x, y >> 1);
			}
			else
			{
				//else return mcd(y, x-y)
				return mcd(y, x-y);
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值