最大公约数(GCD)的计算方法和代码 欧几里得算法和扩展欧几里得算法

最大公约数

求两个数字间a,b的最大公约数gcd(a,b)和最小公倍数lcm(a,b),是很常见的数字计算问题,求除了最大公约数,自然就求除了最小公倍数,求解最大公约数有以下几种方法
l c m ( a , b ) = a / g c d ( a , b ) b lcm(a,b)=a/gcd(a,b)*b 小心计算a*b时溢出,所以先除后乘

质因数分解法

通过分解质因数得到a,b的所有质因子,然后求出最大公约数

辗转相除法(欧几里得算法)

辗转相除法又被称为欧几里得算法,是求两个数a,b间的最大公约数比较常用的算法。它的数学基础是 G C D ( a , b ) = G C D ( b , a m o d b ) GCD(a,b)=GCD(b,a mod b) ,代码有两种写法,迭代和递归
递归:

int GCD(int a,int b){
	return b==0?a:gcd(b,a%b);
}

迭代:

int GCD(int a,int b){
	int t;
	while(b){
		t=a;
		a=b;
		b=a%b;
	}
	return a;
}

辗转相减法(更相替损法)

辗转互减法正如它的名字,两个数互减,大数减小数
递归:

int GCD(int a,int b){
	return b==0?a:GCD(abs(a-b),min(a,b));
}

int GCD(int a,int b){
	if(a==b) return a;
	if(a>b) return GCD(a-b,b);
	return GCD(b-a,a); 
}

迭代:

int GCD(int a,int b){
	while(a!=b){
		if(a>b) a-=b;
		else b-=a;
	}
	return a;
}

快速GCD算法

int qGCD(int a,int b){
	int ans=1,t;
	while(a&&b){
		if(!(a&1) && !(b&1)){
			a>>=1;
			b>>=1;
			ans<<=1;
		}else if(!(a&1)) a>>=1;
		else if(!(b&1)) b>>1;
		else{
			if(a>b) a-=b;
			else if(a<b) b-=a;
			else break;
		}
	}
	if(a==0) return b*ans;
	if(b==0) return a*ans;
}

欧几里得算法和扩展欧几里得算法

用来求解 a x + b y = g c d ( a , b ) ax+by=gcd(a,b)

int exGCD(int a,int b,int &x,int &y){
	if(b==0){
		x=1;
		b=0;
		return a;  //返回GCD(a,b)
	}
	int ans=exGCD(b,a%b,x,y);
	int t=x;
	x=y;
	y=t-a/b*y;
	return ans;
}
int x,y;
int exGCD(int a,int b){
	if(b==0){
		x=1;
		b=0;
		return a;  //返回GCD(a,b)
	}
	int ans=exGCD(b,a%b);
	int x2=x;
	x=y;
	y=x2-a/b*y;
	return ans;
}
发布了50 篇原创文章 · 获赞 0 · 访问量 687

猜你喜欢

转载自blog.csdn.net/zpf1998/article/details/104186478