辗转相除法与更相减损术

大兔子大兔子 提交于 2020-04-07 07:26:45

          已知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


这样求最小公倍数和求最大公约数就是同一个问题了,你还不会么?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!