线性筛选法求质数

还是之前的问题,求出MAXSIZE以内的所以质数

下面我们看下原理

所有的合数都可以分解为两个数的乘积,那么我们建立一个isPrime[MAXSIZE+1]的表,先把所有的元素设置成默认为是质数,true,设置两重循环,将i*j处的值设置成false,这样最后得到的是true元素对应的角标就是质数了,下面附上代码:

#include <iostream>
#include <time.h>
using namespace std;

#define max 99999
int prime[max+1];
bool isPrime[max+1];
int count = 0;

int main()
{
    for (int i = 0;i <= max;i++)
    {
        prime[i] = 0;
        isPrime[i] = true;
    }
    clock_t start,end;//用于计时
    start = clock()    ;
    for (int i = 2;i <= max;i++)
    {
        for(int j = 2;j <= max && i*j <= max;j++)
        {
            isPrime[i*j] = false;
        }
    }
    end = clock();
    for(int i = 2;i <= max;i++)
    {
        if (isPrime[i])
        {
            cout<<i<<" ";
        }
    }
    cout<<"
总共花费了"<<(long double)(end - start)/CLOCKS_PER_SEC<<""<<endl;
    return 0;
}

这里我们可以看到,其实没有经过什么优化,让我们看戏程序的效率:

这个效率已经很高很高了,比之前的筛选法还要高了,下面我们看下在这个算法中还能怎么样去减少循环次数,减小程序的时间复杂度

设想下,在2*4 = 8处和4*2 = 8处,或者 2* 12 = 24和3*8 = 24处,都分别进行了多次赋值,这样看来,效率有所降低,下面是我们优化过的代码,

#include <iostream>
#include <time.h>
using namespace std;

#define max 99999
int prime[max+1];
bool isPrime[max+1];
int count = 0;

int main()
{
    //将数组初始化
    for (int i = 0;i <= max;i++)
    {
        prime[i] = 0;
        isPrime[i] = true;
    }
    clock_t start,end;//用于计时
    start = clock()    ;
    for (int i = 2;i <= max;i++)
    {
        if (isPrime[i])
        {
            prime[count++] = i;
        }
        for(int j = 0;j < count && i*prime[j] <= max;j++)
        {
            isPrime[i*prime[j]] = false;
            if (i % prime[j] == 0)
            {
                break;
            }
        }
    }
    end = clock();
    for(int i = 2;i <= max;i++)
    {
        if (isPrime[i])
        {
            cout<<i<<" ";
        }
    }
    cout<<"
总共花费了"<<(long double)(end - start)/CLOCKS_PER_SEC<<""<<endl;
    return 0;
}
优化过的代码

通过prime数组保存已经得到的质数,然后用这些质数去乘以i得到合数,并将该合数对应的位置置为false,关键还有一个

            if (i % prime[j] == 0)
            {
                break;
            }

操作,比如,当i为8的时候,搜索到2,也就是2*8 = 16,处置为false就可以了,跳出J的循环,因为假如到8*3=24的话 24 = 2*12,可以由一个更大的合数得到,这样就可以减少循环次数,优化时间复杂度,下面看程序运行结果:

这个时间,你懂的!

原文地址:https://www.cnblogs.com/color-my-life/p/3265550.html