各位大佬,转载必须注明一下博客,自己写的不容易。/流眼泪
一 引例:
求两个数的gcd(a,b)=a和b两个数的最大公倍数?
-
短除法
-
更相减损法
-
辗转相除法
1、短除法:
其实短除法的核心 唯一分解定理。我们要求的最大公约数,其实也是它本身的一部分因子。
复杂度
注意:K=gcd(n,m)这个数的因子个数。
我们演示一遍即可。
2、更相减损术:
这个方法是来自我国数学:《九章算术》可以求最大公约数。
复杂度:O(N)
3、辗转相除法:(欧几里德)
复杂度:
图像 小部件
贴上代码:以上三种方法的使用。
#include<bits/stdc++.h>
using namespace std;
void DC(){
int a=888,b=664,gcd=1;
while(1){
int flag=0;
for(int i=2;i<=min(a,b);i++){
if(a%i==0&&b%i==0){
gcd*=i;
a/=i,b/=i;
flag=1;
break;
}
}
if(flag==0){ //两者为互质
break;
}
}
printf("最大公约数:gcd(664,888)=%d\n",gcd);
printf("最小公倍数:lcm(664,888)=%d\n",gcd*a*b);
}
void XJ(){ //更相减损术
int a=888,b=664,temp=0,cnt=0;
while(a-b!=0){
//printf("%d %d %d\n",a,b,temp);
temp=a-b;
a=b;
b=temp;
if(a<b) swap(a,b);
}
printf("%d\n",temp);
}
void GCD(){ //非递归写法
int a=888,b=664,temp;
while(a%b!=0){
temp=a%b;
a=b;
b=temp;
}
printf("%d\n",b);
}
int gcd(int a,int b){//递归写法
return a%b==0?b:gcd(b,a%b);
}
int main()
{
DC();
XJ();
GCD();
cout<<gcd(664,888)<<endl;
}
二 拓展欧几里德:
上面提到了欧几里德,大家都看出来了,仅仅处理了一个小问题,就是计算一个最大公约数。
但是,这个计算公约数速度非常快,可以达到log级别的都是优质算法。
我们只是提及一下短除法和更相减损法,但是有时候面对小的数字,我们可以