[经典算法] Eratosthenes筛选求质数

题目说明:

除了自身之外,无法被其它整数整除的数称之为质数,要求质数很简单,但如何快速的求出质数则一直是程式设计人员与数学家努力的课题,在这边介绍一个著名的 Eratosthenes求质数方法。

题目解析:

首先知道这个问题可以使用回圈来求解,将一个指定的数除以所有小于它的数,若可以整除就不是质数,然而如何减少回圈的检查次数?如何求出小于N的所有质数?
首先假设要检查的数是N好了,则事实上只要检查至N的开根号就可以了,道理很简单,假设A*B = N,如果A大于N的开根号,则事实上在小于A之前的检查就可以先检查到B这个数可以整除N。不过在程式中使用开根号会精确度的问题,所以可以使用 i*i <= N进行检查,且执行更快。
再来假设有一个筛子存放1~N,例如:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ........ N

先将2的倍数筛去:

2 3 5 7 9 11 13 15 17 19 21 ........ N

再将3的倍数筛去:

2 3 5 7 11 13 17 19 ........ N

再来将5的倍数筛去,再来将7的质数筛去,再来将11的倍数筛去........,如此进行到最后留下的数就都是质数,这就是Eratosthenes筛选方法(Eratosthenes Sieve Method)。
检查的次数还可以再减少,事实上,只要检查6n+1与6n+5就可以了,也就是直接跳过2与3的倍数,使得程式中的if的检查动作可以减少。

程序代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <gtest/gtest.h>
using namespace std;

vector<int> EratosthenesPrime(int nSize)
{
    bool* Primes = new bool[nSize];
    memset(Primes, true, sizeof(bool)* nSize);

    for (int i=2; i * i <= nSize; ++i)
    {
        if (Primes[i])
        {
            for (int j = i*i; j < nSize; j+=i)
            {
                Primes[j] = false;
            }
        }
    }

    vector<int> Result;
    for (int i=2; i < nSize; ++i)
    {
        if (Primes[i])
        {
            Result.push_back(i);
        }
    }

    delete[] Primes;

    return Result;
}

TEST(Algo, tEratosthenesPrime)
{
    vector<int> Result = EratosthenesPrime(100);
    cout << "N:100  " << Result.size() << endl;
    for (vector<int>::size_type i=0; i<Result.size(); ++i)
    {
        if (i % 16 == 0)
            cout << endl;

        cout << Result[i] << " ";
    }
    cout << endl << endl;

    Result = EratosthenesPrime(500);
    cout << "N:500  " << Result.size() << endl;
    for (vector<int>::size_type i=0; i<Result.size(); ++i)
    {
        if (i % 16 == 0)
            cout << endl;

        cout << Result[i] << " ";
    }
    cout << endl << endl;

    Result = EratosthenesPrime(1000);
    cout << "N:1000  " << Result.size() << endl;
    for (vector<int>::size_type i=0; i<Result.size(); ++i)
    {
        if (i % 16 == 0)
            cout << endl;

        cout << Result[i] << " ";
    }
    cout << endl << endl;
}

参考引用:

https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

时间: 2024-10-06 14:26:39

[经典算法] Eratosthenes筛选求质数的相关文章

Eratosthenes筛选求质数

由于作者不习惯该编辑器,只是贴出上本文的截图,详见:https://www.yuque.com/docs/share/d9931edf-d754-49b5-bfc4-6b7be6ab577b 原文地址:http://blog.51cto.com/4754569/2326295

经典算法之动态规划--求最大公共子序列

作为新人,之前对C,C++了解的比较少,关于算法方面更是一窍不通,但最近却痴迷上了算法,哪怕是前辈们不屑一顾的东东,我弄明白了后都会欣喜若狂! 今天将遇到的问题和java实现贴出来和同为新人的博友分享,老鸟可以可以直接关网页了. 定义: 子序列:一个给定序列的子序列是再该序列中删去若干元素后得到的序列.即:给定{x1,x2,...,xm}和Z={z1,z2,...,zk},X的子序列是指存在一个严格递增下表序列{i1,i2,...ik} 使得对所有的j=1,2,...k,都有zj=xij.例如:

【经典算法大全】收集51种经典算法 初学者必备

<经典算法大全>是一款IOS平台的应用.里面收录了51种常用算法,都是一些基础问题.博主觊觎了好久,可悲哀的是博主没有苹果,所以从网上下了老奔的整理版并且每个都手敲了一遍. 虽然网上也有博客贴了出来,但是自己写写感觉总是好的.现在分享个大家. 代码和运行结果难免有出错的地方,请大家多多包涵. 1.河内之塔(汉诺塔) 2.费式数列 3.巴斯卡三角形 4.三色棋 5.老鼠走迷宫(1) 6.老鼠走迷宫(2) 7.骑士走棋盘 8.八皇后 9.八枚银币 10.生命游戏 11.字串核对 12.双色河内塔,

经典算法大全

原文地址:经典算法大全 作者:liurhyme 经                                                                    典                                                                    算                                                                    法                  

java 经典算法(转)

1.河内之塔.. 2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇后 9.Algorithm Gossip: 八枚银币. 10.Algorithm Gossip: 生命游戏. 11.Algorithm Gossip:

java学习-4 经典算法

1.河内之塔.. 2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇后 9.Algorithm Gossip: 八枚银币. 10.Algorithm Gossip: 生命游戏. 11.Algorithm Gossip:

Eratosthenes筛选法计算质数

<C和指针>第6章第4道编程题: 质数就是只能被1和本身整除的数.Eratosthenes筛选法是一种计算质数的有效方法.这个算法的第一步就是写下所有从2至某个上限之间的所有整数.在算法的剩余部分,遍历整个列表并剔除所有不是质数的整数. 后面的步骤是这样的.找到列表中的第1个不被剔除的数(也就是2),然后将列表后面所有逢双的数都剔除,因为它们都可以被2整除,因此不是质数.接着,再回到列表的头部重新开始,此时列表中第一个尚未被剔除的第1个数是3,所以在3之后把每逢第3个数(3的倍数)剔除.完成这

C语言求质数的算法

前言 上次被出了一题质数的C语言求解题目(面试),当时用了最粗暴的算法,回来仔细参考资料,其实答案有很多种: 1,小学生版本: 判断 x 是否为质数,就从 2 一直算到 x-1. static rt_uint32_t array1[ARRAY_LEN]; void func1(void) { for (rt_uint32_t i = 1; i <= ARRAY_LEN; i++) { array1[i - 1] = 0; } rt_uint32_t x, y = 0, z = 0; rt_uin

求质数的各种算法

首先声明本人水平有限,仅仅做一下记录,有错的地方请指正,文章垃圾请包容!! 在网上不小心浏览到一篇技术博客,叫做<求质数算法的N种境界(N>10)>,写得很好,有兴趣的读者自己去搜索.然后就想自己去试试这篇博客里写得各种求质数的方法. 不想搭环境,就暂时用了PHP语言,在apache里运行,简易测试一下. 首先明确一下概念 质数(prime number)又称素数,有无限个.质数定义为在大于1的自然数中, 除了1和它本身以外不再有其他因数的数称为质数. 100以内质数表 2 3 5 7