zoukankan      html  css  js  c++  java
  • 素数筛选

    素数筛选目的是筛选出某一区间[m, n)内的所有素数,常见方法包括如下几种:

    1.朴素的筛选法:

    先写出判断函数isPrime(),再对区间内的数依次调用isPrime()进行判断,算法核心是以2~根号n作为除数。

    #include <math.h>
    
    bool isPrime(int n)
    {
        /*
            C++中sqrt有两个重载函数,参数可以是double或float,由于传入参数是int,在默认的隐式类型转换中int可以
            转换成float也可以转换为double,则须通过强转告诉编译器该调用哪一个函数。
        */
        int sqr = (int)sqrt(double(n));
        for(int i = 2; i <= sqr; i++)
        {
            if(n%sqr == 0)
                return false;
        }
        return true;
    }

    2.高效的筛选法之一:

    借助标记数组,对于2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23……初始时均标记素数,模拟如下剔除合数的过程:

    从区间首部开始往后依次考察,如果当前m被标记为素数,那么2*m, 3*m, 4*m……都要标记为合数;如果m被标记为合数,则跳过继续考察m+1……当整个区间全部考察完后,所有素数和合数对照标记数组一目了然。

       考察2时:2,3,5,7,9,11,13,15,17,19,21,23……;

       考察3时:2,3,5,7,11,13,17,19,23……;

       考察4时:直接跳过,因为其后如果有4的倍数而作为合数被剔除,那么在考察2时就已执行,此时已无意义;

       考察5时:2,3,5,7,11,13,17,19,23……;

       ……

    这种算法的核心思想:

    如果在考察到某一个数时,发现它仍然没有在前面多轮剔除合数的过程中被剔除掉,那么它不是此前任何数的倍数,即必定是素数;

    接下来剔除其后与其成倍的数,因为这个剔除过程并不是前面某个剔除过程的子集,所以必定有意义。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    #define N 100
    
    bool isPrime[N+2];
    
    void process()
    {
        int i, j;
        memset(isPrime, true, sizeof(isPrime));
        for(i=2; i<=N; i++)
        {
            if(isPrime[i])
            {
                for(j=i+i; j<=N; j+=i)
                    isPrime[j] = false;
            }
        }
    }
    
    int main()
    {
        process();
        for(int k=2; k<=N; k++)
        {
            if(isPrime[k])
                cout << k << " ";
        }
        return 0;
    }

    3.高效的筛选法之二

    从区间首部开始遍历,并始终维护一个当前已找到素数的集合,如果当前考察数据都不能被素数集合中的数整除,则作为素数将其加入集合中……依次迭代到区间末尾,最终集合即为结果。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    #define N 100
    
    int prime[N+2];
    int pLen;
    
    void setPrime()
    {
        prime[0] = 2;
        pLen = 1;
    
        bool isPrime;
        for(int i=3; i<=N; i++)
        {
            isPrime = true;
            for(int j=0; j<pLen; j++)
            {
                if(i%prime[j] == 0)
                {
                    isPrime = false;
                    break;
                }
            }
            if(isPrime)
                prime[pLen++] = i;
        }
    }
    
    int main()
    {
        setPrime();
        for(int k=0; k<pLen; k++)
        {
            cout << prime[k] << " ";
        }
        return 0;
    }
  • 相关阅读:
    Objective-C Memory Management Being Exceptional 异常处理与内存
    Objective-C Memory Management 内存管理 2
    c语言全局变量与局部变量(当变量重名时)的使用情况
    c语言指针字符串与字符数组字符串的区别
    c语言数组不同初始化方式的结果
    补码的用途
    struts2框架加载配置文件的顺序
    CSS盒子模型
    基于注解整合struts2与spring的时候如果不引入struts2-spring-plugin包自动装配无效
    @Resource注解省略name属性后的行为
  • 原文地址:https://www.cnblogs.com/1203ljh/p/4640958.html
Copyright © 2011-2022 走看看