快速gcd vs 普通gcd

来源:互联网 发布:贵州轩通大数据正规吗 编辑:程序博客网 时间:2024/05/17 05:52

听说快速gcd很快,于是我就突发奇想,看看它到底有多快

普通gcd函数:

ll gcd(ll a,ll b){    ll m=a%b;    while(m){        a=b;b=m;        m=a%b;    }    return b;}

快速gcd函数:

ll kgcd(ll a,ll b){    ll s=1,c;    while(a&&b){        if((~a&1)&&(~b&1))            a>>=1,b>>=1,s<<=1;        else if(~a&1)a>>=1;        else if(~b&1)b>>=1;        else if(a>b)a=a-b;        else c=b-a,b=a,a=c;    }    if(!a)return b*s;    if(!b)return a*s;}

* 第一场 *
随机生成了20组数据,每组数据里有1000,000个大数对,gcd大多为1
数据生成器:

#include<bits/stdc++.h>using namespace std;typedef long long ll;ll _rand(){    return abs((ll)rand()*134982003ll+rand()*32498ll+rand()+1); }ll gcd(ll a,ll b){    return a%b==0?b:gcd(b,a%b); }int main(){    int m=1000000;    srand(time(0));    string fil="gcd";    for(int i=1;i<=20;++i){        printf("Finishing %d...\n",i);        char str[5];sprintf(str,"%d",i);        FILE* in=fopen((fil+str+".in").c_str(),"w");        FILE* out=fopen((fil+str+".out").c_str(),"w");        fprintf(in,"%d\n",m);        for(int i=1;i<=m;++i){            ll a=_rand(),b=_rand();            fprintf(in,"%lld %lld\n",a,b);            fprintf(out,"%lld\n",gcd(a,b));        }           printf("Complete.\n");        fclose(in);        fclose(out);    }}

运行结果如下:
普通gcd 用时 23.55s
快速gcd 用时 35.08s
第一场, 普通gcd获胜!!!

* 第二场 *
随机生成了20组数据,每组数据里有1000,000个大数对,gcd都较大
数据生成器:

#include<bits/stdc++.h>using namespace std;typedef long long ll;ll __rand(){    return rand()%20+1; }ll ___rand(){    return __rand()*__rand()*__rand()*__rand()*__rand()*__rand();}ll _rand(){    return abs((ll)___rand()*___rand()*___rand()); }ll gcd(ll a,ll b){    return a%b==0?b:gcd(b,a%b); }int main(){    int m=1000000;    srand(time(0));    string fil="gcd";    for(int i=1;i<=20;++i){        printf("Finishing %d...\n",i);        char str[5];sprintf(str,"%d",i);        FILE* in=fopen((fil+str+".in").c_str(),"w");        FILE* out=fopen((fil+str+".out").c_str(),"w");        fprintf(in,"%d\n",m);        for(int i=1;i<=m;++i){            ll a=_rand(),b=_rand();            fprintf(in,"%lld %lld\n",a,b);            fprintf(out,"%lld\n",gcd(a,b));        }           printf("Complete.\n");        fclose(in);        fclose(out);    }}

运行结果如下:
普通gcd 用时 28.53s
快速gcd 用时 34.84s
第二场, 普通gcd获胜!!!

* 第三场 *
随机生成了20组数据,每组数据里有1000,000个数对(一大一小),gcd几乎都为1(数据生成器与前面大同小异,略过)

运行结果如下:
普通gcd 用时 15.52s
快速gcd 用时 26.98s
第三场, 普通gcd获胜!!!

* 第四场 *
随机生成了20组数据,每组数据里有1000,000个数对(一大一小),gcd都较大(数据生成器与前面大同小异,略过)

运行结果如下:
普通gcd 用时 18.41s
快速gcd 用时 28.32s
第四场, 普通gcd获胜!!!

综上,普通gcd完美战胜快速gcd!!!
但是,位运算不是比mod快XXX倍吗。。。
我猜测,快速gcd虽然运算快,但循环多,在随机数据面前表现不佳。
(除了gcd(2^a,2^b)脑残数据。。。)
所以,快速gcd才被秒杀了

0 0
原创粉丝点击