您的位置:首页 > 编程语言 > C语言/C++

C++求最小公倍数和最大公约数问题

2017-03-12 16:45 274 查看


这道题的解答就是求三个数(假设为x,y,z)的最小公倍数,通过转化,这个最小公倍数可以转化成x*y*z÷最大公约数(x,y)÷最大公约数(x*y,z);所以问题的解答就变成了如何求最大公约数的问题上了。

而求最大公约数的最直接方法是欧几里得法,简单说就是(a,b)两个数的最大公约数等于(b,a%b)%为取余运算符。举个例子(42,24)=(24,18)=(18,6)=(6,0),所以最大公约数就是6;通过迭代就能简单求解。(这里要保证第一个数大于第二个数,若不满足,则将两个数的位置颠倒,如(0,6)=(6,0))

但是取余的开销还是蛮大的,另一种做法是相减,即(a,b)=(b,a-b),此处跟上面一样,假设a>b,若小于则两个数颠倒位置。但是减法的坏处是操作次数太多,比如求(100000,1)这种要操作很多很多次。那有没有又避免取余开销,又减少操作次数的呢,那就是将两种操作结合起来啦。

假设p是一个素数,注意是素数。b=p*n.则(a,b)=(a,n)(这里假设p不能被a整除),而我们知道2是一个最小素数,而且对2取余,实际可用通过位操作实现,开销很小。那如果p可以被a整除呢,假设a=p*m,b=p*n,则(a,b)=p*(m,n).所以写成的程序如下:

#include<iostream>

using namespace std;

int Fun(int a,int b){
if(b==0){
return a;
}
if(a<b)
return Fun(b,a);
if(a&1){
if(b&1)
return Fun(b,a-b);
else
return Fun(a,b>>1);
}
else{
if(b&1)
return Fun(a>>1,b);
else
return 2*Fun(a>>1,b>>1) ;
}
}

int main(){
int x,y,z;
int result=0;
while(cin>>x>>y>>z){
int a=Fun(x,y);
int b=Fun(x*y,z);
result=x*y*z/a/b;
cout<<result<<endl;
}
return 0;
}


代码风格比较丑,大家将就看看,还有上面欧几里得法之类的证明大家可以百度,或者自行证明,并不难。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐