【编程之美】2.7求最大公约数

注:下面的解法中都没有考虑超大数,就是无法直接表示的数。如果有的话需要自己定义超大数,并定义相应的操作。

#include <stdio.h>

//辗转相除法 缺点求余操作用到除法 非常耗时
int gcd1(int x, int y)
{
    return (!y) ? x : gcd1(y, x % y); //不需要大数在前,因为就算小一些的数字在前面 gcd一次后也变成大数在前了
}

//最大公约数可以同时被x 、y整除则 也可以被 x - y, y整除
//缺点 循环次数很多
int gcd2(int x, int y)
{
    int a = (x > y) ? x : y;
    int b = (x < y) ? x : y;

    return (!b) ? a : gcd2(a - b, b);
}

//如果p是质数 x % p == 0 , y % p != 0 那么 gcd(x,y) = gcd(x/p, y);
//2是质数 且除以2可以用移位操作
//如果 x,y 都是偶数 gcd(x,y) = 2 * gcd(x>>1, y>>1);
//如果 x是偶数,y是奇数 gcd(x,y) = gcd(x>>1, y);
//如果 x是奇数,y是偶数 gcd(x,y) = gcd(x, y>>1);
//如果 x,y 都是奇数 gcd(x,y) = gcd(x-y, y);
//时间复杂度O(log2(max(x,y)))
int gcd3(int x, int y)
{
    if(x < y)
        return gcd3(y, x);
    if(y == 0)
    {
        return x;
    }
    else if(x & 0x0001 == 0)
    {
        if(y & 0x0001 == 0)
            return (gcd3(x>>1, y>>1) << 1);
        else
            return gcd3(x>>1, y);
    }
    else
    {
        if(y & 0x0001 == 0)
            return gcd3(x, y>>1);
        else
            return gcd3(x - y, y);
    }
}



int main()
{
    int r = gcd1(42, 30);
    int b = gcd2(42, 30);
    int c = gcd3(42, 30);

    return 0;
}

 

posted @ 2014-10-31 13:38  匡子语  阅读(327)  评论(0编辑  收藏  举报