zoukankan      html  css  js  c++  java
  • 线性筛选法求质数

    还是之前的问题,求出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,可以由一个更大的合数得到,这样就可以减少循环次数,优化时间复杂度,下面看程序运行结果:

    这个时间,你懂的!

  • 相关阅读:
    javaIO流之 字节与字符流认识
    Servlet容器理解(生命周期、servletContext作用域、servlet装载方式)
    是否改变原数组的常用方法
    时间空间复杂度的初步理解---后续补充
    java集合框架之 Set
    【原】SQLPLUS支持上下翻页
    【转】shell脚本写的俄罗斯方块游戏
    【原】Oracle 11.2.0.1 64bit for RHEL6.0 Server x86_64 静默安装
    【原】RHEL6.0企业版安装
    【原】记录一句话
  • 原文地址:https://www.cnblogs.com/color-my-life/p/3265550.html
Copyright © 2011-2022 走看看