欧几里得算法和Stein算法【数论】

欧几里得算法:

int gcd(int a,int b)
{
	return b?gcd(b,a%b):a;
}
定理:两个整数的最大公约数等于其中较小的那个数和两数的相除余数的最大公约数。 最大公约数 (greatest common divisor)缩写为gcd。

将一个2个数的除法写成带余除法的形式:

y=ax+b

则b=y%x

欧几里得算法便基于如下恒等式

gcd(a,b)=gcd(b,a%b)

也就是辗转相除法

辗转相除法是利用以下性质来确定两个正整数 a 和 b 的最大公因子的:
⒈ 若 r 是 a ÷ b 的余数,且r不为0, 则
gcd(a,b) = gcd(b,r)
⒉ a 和其倍数之最大公因子为 a。
另一种写法是:
⒈ 令r为a/b所得余数(0≤r<b)
若 r= 0,算法结束;b 即为答案。
⒉ 互换:置 a←b,b←r,并返回第一步。
欧几里得算法在longlong以内还可,但如果是超过了longlong的就比较慢;

优化:Stein算法

这个方法也是计算两个数的最大公约数。和欧几里德算法不同的是,Stein算法只有整数的移位和加减法,这对于程序设计者是一个福音。
gcd(a,a) = a,也就是一个数和他自身的公约数是其自身
gcd(ka,kb) = k gcd(a,b),也就是最大公约数运算和倍乘运算可以交换,特殊的,当k=2时,说明两个 偶数的最大公约数必然能被2整除
int gcd(int a,int b)
{
	if(a<b) //arrange so that a>b
	{int temp = a;a = b;b=temp;}
	if(0==b) //the base case
		return a;
	if(a%2==0 && b%2 ==0) //a and b are even
		return 2*gcd(a/2,b/2);
	if (a%2 == 0) // only a is even
		return gcd(a/2,b);
	if (b%2==0)// only b is even
		return gcd(a,b/2);
		return gcd((a-b)/2,b);// a and b are odd
}

你可能感兴趣的:(算法,数论)