快速查找质数

普通算法:

void findZhishu()
{

    int  n,m,flag,i,j,num=0;
    printf("n:");
    scanf("%d",&n);
    printf("从2到%d的质数如下:\n",n);
    clock_t bt = clock();
//    printf("===now time:%lu===",bt);
    for(i=2;i<=n;i++)//循环查找质数
    {
        flag=1;
        m=(int)sqrt(i);
        for(j=2;j<=m;j++)
        {
            if(i%j==0)//条件为真时表示不是质数,退出for循环
            {
                flag=0;
                break;
            }
        }

        if(flag==1)//条件为真时表示i是质数
        {
            num ++;
            printf("%4d\t",i);
            if(num%10==0)//每行最多输出10个数
                printf("\n");
        }
    }
    printf("\n");
    printf("===count:%d \n",num);
    printf("===used:%fS===",(float)(clock()-bt)/CLOCKS_PER_SEC);
    printf("\n");
}

高效率算法(转载)

int Sieve()
{
    int n;
    clock_t bt = clock();
    printf("n:");
    scanf("%d",&n);
    int i, j;
    //素数数量统计
    int count = 0;
    // 分配素数标记空间,明白+1原因了吧,因为浪费了一个flag[0]
    char* flag = (char*)malloc( n+1 );
    // 干嘛用的,请仔细研究下文
    int mpLen = 2*3*5*7*11*13;
    char magicPattern[2*3*5*7*11*13]; // 奇怪的代码,why,思考无法代劳,想!
    for (i=0; i<mpLen; i++)
    {
        magicPattern[i++] = 1;
        magicPattern[i++] = 0;
        magicPattern[i++] = 0;
        magicPattern[i++] = 0;
        magicPattern[i++] = 1;
        magicPattern[i] = 0;
    }
    for (i=4; i<=mpLen; i+=5)
        magicPattern[i] = 0;
    for (i=6; i<=mpLen; i+=7)
        magicPattern[i] = 0;
    for (i=10; i<=mpLen; i+=11)
        magicPattern[i] = 0;
    for (i=12; i<=mpLen; i+=13)
        magicPattern[i] = 0;
    // 新的初始化方法,将2,3,5,7,11,13的倍数全干掉
    // 而且采用memcpy以mpLen长的magicPattern来批量处理
    int remainder = n%mpLen;
    char* p = flag+1;
    char* pstop = p+n-remainder;
    while (p < pstop)
    {
        memcpy(p, magicPattern, mpLen);
        p += mpLen;
    }
    if (remainder > 0)
    {
        memcpy(p, magicPattern, remainder);
    }
    flag[2] = 1;
    flag[3] = 1;
    flag[5] = 1;
    flag[7] = 1;
    flag[11] = 1;
    flag[13] = 1;
    // 从17开始filter,因为2,3,5,7,11,13的倍数早被kill了
    // 到n/13止的,哈哈,少了好多吧
    int stop = n/13;
    for (i=17; i <= stop; i++)
    {
        // i是合数,请歇着吧,因为您的工作早有您的质因子代劳了
        if (0 == flag[i]) continue;
        // 从i的17倍开始过滤
        int step = i*2;
        for (j=i*17; j <= n; j+=step)
        {
            flag[j] = 0;
        }
    }

    // 统计素数个数
    for (i=2; i<=n; i++)
    {
        if (flag[i]){
            count++;
            printf("%d|", i);
        }
    }

    // 因输出费时,且和算法核心相关不大,故略
    // 释放内存,别忘了传说中的内存泄漏
    free(flag);

    printf("===count:%d",count);
    printf("===used:%f",(float)(clock()-bt)/CLOCKS_PER_SEC);

    return count;
}
posted @ 2016-02-26 15:00  随风的博客  阅读(343)  评论(0编辑  收藏  举报