首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

小弟我的求素数的程序,大家看看是不是最快的?还能不能优化

2012-08-11 
我的求素数的程序,大家看看是不是最快的?还能不能优化?C/C++ code#include iostream#include math.hus

我的求素数的程序,大家看看是不是最快的?还能不能优化?

C/C++ code
#include <iostream>#include <math.h>using namespace std;int get_prime(int n)//求第n个素数{    int *p_r = new int[n];    int count = 1;    p_r[0] = 2;    p_r[1] = 3;    for(int i=3; count!=n; i+=2)    {        int sqrt_i = sqrt(i);        for(int j=1; sqrt_i>=p_r[j] && i%p_r[j]!=0; ++j);        if(sqrt_i<p_r[j])        {            p_r[count++] = i;        }    }    return p_r[count-1];}int main(){    cout<<get_prime(10000000)<<endl;    //第一千万个素数:179424673    return 0;}


[解决办法]
话说可以把你的函数作为内联函数
[解决办法]
C/C++ code
#include <iostream>#include <cmath>#include <cstring>using namespace std;/*********************************/*   gcd(int a,int b)*   原名:欧几里得算法*   辗转相除法求最大公约数*   无所谓a,b大小次序./*********************************/int gcd(int a,int b){    return b==0 ? a : gcd(b,a%b);}/*********************************/*   lcm(int a,int b)*   求最小公倍数*   无所谓a,b大小次序./*********************************/int lcm(int a,int b){    return a/gcd(a,b)*b; //mark:计算顺序防止乘法溢出}/*********************************/*   int prime(int n)*   筛法构造2....n的素数表*   O(nlgn)/*********************************/const int MAXSIZE=10000000;int p[MAXSIZE];int vis[MAXSIZE];int prime(int n){    int m=sqrt(n+0.5);    int c=0;    memset(vis,0,sizeof(vis));    for(int i=2;i<=m;++i)    {        if(!vis[i])        {            p[c++]=i;        }        for(int j=i*i;j<=n;j+=i)        {            vis[j]=1;        }    }    for(int k=m+1;k<=n;++k)    {        if(!vis[k])        {            p[c++]=k;        }    }    return c;}/******************************************/*   调用bool result(int a,int b,int c,int &x,int &y);*   gcd1(int a,int b,int &d,int &x,int &y)*   扩展欧几里得算法*   解整系数线性方程:ax+by=c*   d为最大公约数,x,y为解./*******************************************/void gcd1(int a,int b,int &d,int &x,int &y){    if(!b)    {        d=a;        x=1;        y=0;    }    else    {        gcd1(b,a%b,d,y,x);        y-=x*(a/b);    }}bool result(int a,int b,int c,int &x,int &y){    int d;    gcd1(a,b,d,x,y);    if(c%d==0)    {        x=x*c/d;        y=y*c/d;        return true;    }    else    {        return false;    }}/******************************************/* 模运算公式:* (a+b)mod n= ((a mod n)+ (b mod n)) mod n* (a-b)mod n=  ((a mod n)-(b mod n)+ n) mod n* a*b mod n= ( (a mod n) *(b mod n) ) mod n*  a*b特殊,(a mod n) *(b mod n) 可能溢出,*  用long long 保存中间计算过程, mod n后转回int*  感觉其他两种也不是说不可能溢出,万一n很大,a,b也大*  中间的计算过程依旧会溢出,所以最好都用long long*  保存中间运算的值,运算结束(int)转化回去/*******************************************//*********************************/*大整数取模运算,输入正整数 n ,m*输出n mod m, 其中n<=10e100, m<=10e9(m在int范围内)*n太大,用字符串存储,m用int存储*例如:n=1234, 可以分解:*1234=((((0*10)+1)*10+2)*10+3)*10+4   mod n*由于只有*,+运算,可以将mod放进去/*********************************/char input[200];int bigMod(char *n,int m){    int len=strlen(n);    int mod=0;    for(int i=0;i<len;++i)    {        mod=(int)(((long long )mod*10+n[i]-'0') % m);    }    return mod;}/*********************************/*幂取模*输入正整数a,n,m,求aEn mod m*a,n,m <=10e9*0(n)算法,O(lgn)算法/*********************************/int nPowMod(int a,int n,int m){    int ans=1;    for(int i=0;i<n;++i)    {        ans=(int)((long long )ans*a%m);    }    return ans;}int nlgnPowMod(int a,int n,int m){    if(n==1)    {        return a%m;    }    else    {        int ret=nlgnPowMod(a,n/2,m);        long long mod=(long long )ret*ret%m;        if(n%2==1)        {            mod=(mod*a)%m;        }        return (int)mod;    }}int main(){    //最大公约数gcd()    cout<<gcd(30,14)<<endl;    //最小公倍数lcm()    cout<<lcm(5,9)<<endl;    //打1.....1e6的素数表    int cnt=prime(10);    for(int i=0;i<cnt;++i)    {        cout<<p[i]<<",";    }    cout<<endl;    //求解形如:ax+by+c=0 的整系数线性方程    int a=6,b=15,c=9,x,y;    if(result(a,b,c,x,y))    {        cout<<"其中一组解为:"<<x<<","<<y<<endl;    }    //大整数取模   // memset(input,0,sizeof(input));   // cin>>input;    //cout<<bigMod(input,100);    //幂取模    cout<<nPowMod(2,100000,500)<<endl;    cout<<nlgnPowMod(2,100000,500)<<endl;    return 0;} 


[解决办法]

C/C++ code
// 普通的筛素数方法与改进之后的效率对比#include<iostream>#include<cmath>#include<cstdio>using namespace std;#include<memory.h>#include<time.h>const int MAXN = 10000000;bool flag[MAXN];int prime[664600], num;         //10^7//int prime[5761500], num;      //10^8int bit[MAXN / 32];// 利用对每个素数的倍数必定不是素数来筛选void GetPrime_1(){    int i, j;    num = 0;    memset(flag, false, sizeof(flag));    for (i = 2; i < MAXN; ++i)    {        if (!flag[i])        {            prime[num++] = i;            for (j = i; j < MAXN; j += i)                flag[j] = true;        }    }    cout<<num<<endl;}// 利用了奇偶性来筛选void GetPrime_2(){    int i, j;    prime[0] = 2;    num = 1;    memset(flag, false, sizeof(flag));    for (i = 3; i < MAXN; i+=2)    {        if (!flag[i])            prime[num++] = i;        for (j = i; j < MAXN; j += i)        {            if(!flag[j])                flag[j] = true;        }    }    cout<<num<<endl;}void GetPrime_3() {     int i,j,k,flag;    prime[0] = 2;    num = 1;    for(i = 3 ; i < MAXN ; i += 2)   //奇数才有可能是素数,偶数就可以直接忽略了    {        k = sqrt(i*1.0);        flag = 0;        for(j = 3 ; j <= k ; j += 2)    //奇数肯定无法整除偶数,所以只需要判断是否能否整除奇数就可以了,只要有一个能够整除,就不是素数        {            if(i % j == 0)            {                flag = 1;                break;            }        }        if(flag == 0)            prime[num++] = i;    }    cout<<num<<endl;}// 利用了每个合数必有一个最小素因子来筛选// 方法最快的筛选方法void GetPrime_4(){    int i, j;    num = -1;    memset(flag, false, sizeof(flag));    for (i = 2; i < MAXN; ++i)    {        if (!flag[i])            prime[++num] = i;        for (j = 0; j <= num  && i * prime[j] < MAXN; ++j)        {            flag[i * prime[j]] = true;            if (i % prime[j] == 0)    //这句保证每个非素数只被筛去一次                 break;        }    }    cout<<num<<endl;}//位操作void GetPrime_5(){    int i, j;      num = 0;      memset(bit, 0, sizeof(bit));      for (i = 2; i < MAXN; i++)    {        if (!((bit[i / 32] >> (i % 32)) & 1))          {            prime[num++] = i;            for (j = i; j < MAXN; j += i)                bit[j / 32] |= (1 << (j % 32));          }    }    cout<<num<<endl;}int main(void){    printf(" 在%d的数据量下普通的筛素数方法与改进之后的效率对比\n", MAXN);    clock_t clockBegin, clockEnd;        clockBegin = clock();    GetPrime_1();    clockEnd = clock();    printf("普通的筛素数方法\t%d毫秒\n", clockEnd - clockBegin);    clockBegin = clock();    GetPrime_2();    clockEnd = clock();    printf("具有奇偶性的筛素数方法\t%d毫秒\n", clockEnd - clockBegin);    clockBegin = clock();    GetPrime_3();    clockEnd = clock();    printf("筛素数方法\t%d毫秒\n", clockEnd - clockBegin);    clockBegin = clock();    GetPrime_4();    clockEnd = clock();    printf("改进的筛素数方法\t%d毫秒\n", clockEnd - clockBegin);    clockBegin = clock();    GetPrime_5();    clockEnd = clock();    printf("位操作筛素数方法\t%d毫秒\n", clockEnd - clockBegin);    system("pause");    return 0;} 

热点排行