已知a、b求a与b的最大公因数与最小公倍数?
先说最大公因数
我们先把a、b改写成多个素数的幂相乘。比如a=36和b=54,那么a=2^2*3^2,b=2^1*3^3。根据定义最大公因数就是取a、b分解出的相同素数的最小指数相乘,即2^1*3^2=18。
辗转相除法就是用a、b中的大数对小数取余,再把余数和小数中的较小数取余,一直这样做,直到刚好整除,余数为0。比如36与54,先算54%36=18,再算36%18=0,结束,这里的18即为所求。
int gcd(int x,int y) { if(x%y==0) return y; else return zhanzhuan(y,x%y); }
然后是更相减损术。一种实现是把a、b中的大数减小数,然后把小数与差中的大数减小数,直到减到减数和差一样,此时的差即为所求。
比如36与54,先算54-36=18,再算36-18=18,此时18=18,18就是最大公因数了。
int gcd(int a,int b) { while(a!=b) { if(a>b)a=a-b; if(a<b)b=b-a; } return a; }
以上两种算法复杂度略玄学,有时快有时慢的……
这里还有一种更相减损术的代码,复杂度是log级别的。
int gcd(int a,int b) { int F=1; while(a!=b) { if(a<b)swap(a,b); if(a&1) if(b&1)a-=b; else b/=2; else if(b&1)a/=2; else a/=2,b/=2,F*=2; } return a*F; }
因为当a、b为奇数时相减,得到偶数,然后执行其他三个操作。也就是说每执行两步操作,必然除掉了一个2。
然后再说最小公倍数。
一种正常的算法是把a、b改写成多个素数的幂相乘。比如a=36和b=54,那么a=2^2*3^2,b=2^1*3^3。最小公倍数就是取所有的素数的最大指数相乘,即2^2*3^3=108。
那么看看这俩方法就可以发现,ab作为两个数,最小公倍数最大公因数一个取最大指数一个取最小指数,那么每一个数分解出的素数的幂肯定都取到两个数中了,那么就有
最小公倍数*最大公约数=a*b
这样求最小公倍数和求最大公约数就是同一个问题了,你还不会么?
来源:https://www.cnblogs.com/qywyt/p/9024161.html