• 筛法求素数


    genPrime和genPrime2是筛法求素数的两种实现,其实是一个思路,表示方法不同而已。

    具体思路在注释中已经含有。

    #include<iostream>  
    #include<math.h>  
    #include<stdlib.h>
    using namespace std;  
    const int MAXV = 100; //素数表范围  
    bool flag[MAXV+1]; //标志一个数是否为素数  
    int prime[MAXV+1]; //素数表,下标从0开始  
    int size=0; //素数个数  
    void genPrime(int max)  
    {  
        memset(flag, true, sizeof(flag));//首先对标签数组进行初始化,全部设为true。  
        for(int i = 2; i <= max / 2; i++)  
        {  
            /* 
            从2开始,删除2的倍数 
            */  
            if(flag[i])  
            {  
                //j=i<<1等价于 j=i*2,即j是i的两倍,而最后的j+=i,则表示下一个循环j是i的3倍,接着4倍。。。
                //i的所有2~N倍数肯定都不是素数,因此将flag置为0,直到最后一位。
                for(int j = i << 1 ; j <= max; j += i)
                {  
                    flag[j] = false;  
                }  
            }  
        }  
        for(int i = 2 ; i <= max; i++)  
        {  
            if(flag[i])  
            {  
                prime[size++] = i;//存储素数。将所有标志位依然为1的标志写入素数数组中去。  
            }  
        }  
    }  
    void genPrime2(int max)  
    {  
        memset(flag, true, sizeof(flag));//首先对标签数组进行初始化,全部设为true。  
        int sq=sqrt((double)max)+1;  //一个数 n 如果是合数,那么它的所有的因子不超过sqrt(n)
        int i,j, k;  
        for(i = 2;i<=sq; i++)  
        {  
            if(flag[i])  
                for(j=2,k=max/i+1;j<k;j++)  
                    flag[i*j] = false; //所有i的j倍都不是素数 
        }  
        for( i = 2 ; i <= max; i++)  
        {  
            if(flag[i])  
            {  
                prime[size++] = i;//存储素数。将所有标志位依然为1的标志写入素数数组中去。  
            }  
        }  
    }  
    int main()  
    {  
    //  genPrime(MAXV);  
        genPrime2(MAXV);  
        //输出所有素数。  
        for(int i=0;i<size;i++)  
            cout<<prime[i]<<" ";
        cout<<endl;
        system("pause");
        return 0;  
    }  
    /*
    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
    请按任意键继续. . .
    */

    ps:补充于2011-6-14

    参考博客:

    1.http://www.cppblog.com/shyli/archive/2007/05/18/24334.html

    2.http://blog.sina.com.cn/s/blog_4b5210840100cm4r.html 

    3.http://blog.hjenglish.com/bedford/archive/2008/10/11/401082.html

          筛法其实就是以空间换时间的一个最好的证明。空间复杂度增加了,时间复杂度降低了。这个斐波那契数列求解类似,如果用递归,那么时间复杂度很慢,如果将用数组存储一个斐波那契数列,则时间复杂度降低到线性。

          上面的参考博客2有一些解释,3则给出了具体的改进算法。有空再研究。

     

    作者:xwdreamer
    欢迎任何形式的转载,但请务必注明出处。
    分享到:
  • 相关阅读:
    剑指offer-面试题23.从上往下打印二叉树
    C++静态成员函数不能调用非静态成员变量
    程序的堆区和栈区
    C++空类的大小
    struct内存对齐
    LeeCode(Database)-Customers Who Never Order
    LeeCode(Database)-Duplicate Emails
    LeeCode(Database)-Employees Earning More Than Their Managers
    LeeCode(Database)-Combine Two Tables
    剑指offer-面试题22.栈的压入,弹出序列
  • 原文地址:https://www.cnblogs.com/xwdreamer/p/2297040.html
Copyright © 2020-2023  润新知