最大公约数GCD
最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个
更相减损法
gcd(a,b)
假设a>b,则gcd(a,b)=gcd(b,a-b)、gcd(a,a)=a
递归版
//更相减损法(递归)
int gcd(int a,int b) {
if(a==b) return a;
return a>b?gcd(a-b,b):gcd(b-a,a);
}
循环版
int gcd(int a,int b) {
while(a-b) {
int c=a-b;
if(c>0) a=c;
else {
b=a;
a=-c;
}
}
return a;
}
辗转相除法
gcd(a,b)=gcd(b,a%b)
gcd(a,a)=a
递归版
int gcd(int a,int b) {
if(!b) return a;
return gcd(b,a%b);
}
循环版
int gcd(int a,int b) {
while(b) {
int c=a%b;
a=b;
b=c;
}
return a;
}
Stein算法
证明见https://blog.csdn.net/d52370/article/details/88577978
a | b | gcd(a,b) (a>b) |
---|---|---|
奇数 | 奇数 | gcd((a+b)/2,(a-b)/2) |
奇数 | 偶数 | gcd(a,b/2) |
偶数 | 奇数 | gcd(a/2,b) 或 gcd(b,a/2) |
偶数 | 偶数 | 2*gcd(a/2,b/2) |
递归版
int stein(int a,int b) {
if(a==0) return b;
if(b==0) return a;
if(a<b) {
a^=b;
b^=a;
a^=b;
}
if(a&1) { //a为奇数
if(b&1) { //a为奇数,b为奇数
return stein1((a+b)>>1,(a-b)>>1);
} else { //a为奇数,b为奇数
return stein1(a,b>>1);
}
} else { //a为偶数
if(b&1) { //a为偶数,b为奇数
return stein1(a>>1,b);
} else {//a为偶数,b为偶数
return stein1(a>>1,b>>1)<<1;
}
}
}
循环版
int stein(int a,int b){
int factor=0;
if(a<b){
a^=b;
b^=a;
a^=b;
}
if(!b) return 0;
while(a!=b){
if(a&1){
if(b&1){//奇+奇
b=(a-b)>>1;
a-=b;
}else{//奇+偶
b>>=1;
}
}else{
if(b&1){//偶+奇
a>>=1;
if(a<b){
a^=b;
b^=a;
a^=b;
}
}else{//偶+偶
factor++;
a>>=1;
b>>=1;
}
}
}
return (a<<factor);
}
最小公倍数LCM
两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数。
int lcm(int a,int b){
return a*b/gcd(a,b);
}