求最大公约数

欧几里德:辗转相除的办法。   

Stein:奇数偶数分开考虑,没有除法,只有移位,加减。

#include <stdio.h>
#include <sys/time.h>
int gcd1(int a, int b)
{
    while (1)
    {
        a = a % b;
        if (a == 0)
            return b;
        b = b % a;
        if (b == 0)
            return a;
    }
}

int gcd0(int M, int N)
{
    int Rem;
    while (N > 0)
    {
        Rem = M % N;
        M = N;
        N = Rem;
    }
    return M;
}

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

}

int gcd3(int a, int b)
{
    if (a < b)
    {                           //arrange so that a>b
        int temp = a;
        a = b;
        b = temp;
    }
    if (0 == b)                 //the base case
        return a;
    if (a % 2 == 0 && b % 2 == 0)       //a and b are even
        return 2 * gcd3(a / 2, b / 2);
    if (a % 2 == 0)             // only a is even
        return gcd3(a / 2, b);
    if (b % 2 == 0)             // only b is even
        return gcd3(a, b / 2);
    return gcd3((a - b) / 2, b); // a and b are odd
}
#define C 100000
#define D 100
int main()
{
    struct timeval starttime, endtime;
    
    // gcd0
    gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        int d = D;
        int i;
        int g;
        while (--c)
        {
            for (i = d; i < 10 * d; i++)
            {
                g = gcd0(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
    /// gcd1
        gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        int d = D;
        int i;
        int g;
        while (--c)
        {
            for (i = d; i < 10 * d; i++)
            {
                g = gcd1(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
    /// gcd 2
        gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        int d = D;
        int i;
        int g;
        while (--c)
        {
            for (i = d; i < 10 * d; i++)
            {
                g = gcd2(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
           
    //gcd 3
    gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        int d = D;
        int i;
        int g;
        while (--c)
        {
            for (i = d; i < 10 * d; i++)
            {
                g = gcd3(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
    return 0;
}
运行:

chen@chen-book1:~$ gcc count.c -o count
chen@chen-book1:~$ ./count
2 s 536068 us
1 s 920305 us
26 s 448318 us
24 s 646252 us

改为:

#define C 100
#define D 100000

则:

chen@chen-book1:~$ ./count
2 s 482367 us
1 s 878122 us
55 s 522424 us
52 s 281608 us
chen@chen-book1:~$


换成cpp版的long long

#include <stdio.h>
#include <sys/time.h>

template <class T>
T gcd1(T a, T b)
{
    while (1)
    {
        a = a % b;
        if (a == 0)
            return b;
        b = b % a;
        if (b == 0)
            return a;
    }
}

template <class T>
T gcd0(T a, T b)
{
    int rem;
    while (b > 0)
    {
        rem = a % b;
        a = b;
        b = rem;
    }
    return a;
}

template <class T>
T gcd2(T a, T b)
{
    if (a < b)
    {
        a ^= b;
        b ^= a;
        a ^= b;
    }
    if (b == 0)
        return a;
    if ((a & 1) == 0 && (b & 1) == 0)
        return 2 * gcd2(a >> 1, b >> 1);
    else if ((a & 1) == 0)
        return gcd2(a >> 1, b);
    else if ((b & 1) == 0)
        return gcd2(a, b >> 1);
    else
        return gcd2((a - b) >> 1, b);
}

template <class T>
T gcd3(T a, T b)
{
    if (a < b)
    {                           //arrange so that a>b
        T temp = a;
        a = b;
        b = temp;
    }
    if (0 == b)                 //the base case
        return a;
    if (a % 2 == 0 && b % 2 == 0)       //a and b are even
        return 2 * gcd3(a / 2, b / 2);
    if (a % 2 == 0)             // only a is even
        return gcd3(a / 2, b);
    if (b % 2 == 0)             // only b is even
        return gcd3(a, b / 2);
    return gcd3((a - b) / 2, b); // a and b are odd
}

#define C 2
#define D 10000*10000*10000LL
#define N 2000
int main()
{
    
    struct timeval starttime, endtime;
    
    // gcd0
    gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        long long d = D;
        long long i;
        long long g;
        while (--c)
        {
            for (i = d; i <  d+N; i++)
            {
                g = gcd0(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
    /// gcd1
        gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        long long d = D;
        long long i;
        long long g;
        while (--c)
        {
            for (i = d; i <  d+N; i++)
            {
                g = gcd1(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
    /// gcd 2
        gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        long long d = D;
        long long i;
        long long g;
        while (--c)
        {
            for (i = d; i < N + d; i++)
            {
                g = gcd2(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
           
    //gcd 3
    gettimeofday(&starttime, 0);
    {
        int c;
        c = C;
        long long d = D;
        long long i;
        long long g;
        while (--c)
        {
            for (i = d; i < N + d; i++)
            {
                g = gcd3(i, i + 1);
            }
        }
    }
    gettimeofday(&endtime, 0);
    if (endtime.tv_usec < starttime.tv_usec)
    {
        endtime.tv_sec--;
        endtime.tv_usec += 1000000;
    }
    printf("%ld s %ld us\n",
           endtime.tv_sec - starttime.tv_sec,
           endtime.tv_usec - starttime.tv_usec);
    return 0;
}

运行:

chen@chen-book1:~$ g++ count.cpp -o count
chen@chen-book1:~$ ./count
0 s 109 us
0 s 188 us
0 s 3998 us
0 s 4206 us

还是这样。。。。第二种Stein还比不上第一种呢。但是我找不到128位以上的整数啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值