繁体   English   中英

修复我在C ++中实现Eratosthenes筛子的实现

[英]Fixing my implementation of Sieve of Eratosthenes in C++

我的算法可以正确运行直到前100个素数,但是出了点问题。 请在下面查看我的代码,我尝试遵循此处给出的伪代码https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

int main()
{
  int n = 1000; //compute primes up to this number
  vector<bool> p(true,n); //all values set to true, from 0 to n

  for(int i = 2; i < sqrt(n)+1; i++){
    if( p[i-1] == true ){
      for(int j = i*i; j < n; j += i) //start looking for multiples of prime i at i*i (optimized)
    p[j-1] = false;
    }
  }

  for(int i = 2; i < n; i++){
    if( p[i-1] == true )
      cout << i << "\n";
  }
  return 0;
}

输出为:

2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
193
199

我完全惊讶该程序完全运行。 它具有不确定行为的绝对负载 !。

除非我非常误解(在这种情况下,请用下降投票来奖励星期五下午的宁静),否则vector<bool> p(true, n)将创建一个大小为true的向量,并将元素初始化为n

您有错误的构造函数参数。 这可以有效地反转大多数值的筛子。

您是否绝对破坏了编译器的警告级别?

首先,您不需要为每个数字存储一个布尔值。 这样,您在浪费内存。 您应该只存储找到的素数,除非您有很好的理由不这样做。

我不会执行代码,因为它会破坏学习的乐趣。 您应该实现以下内容:

  • p初始化为整数向量。
  • 将2作为第一个值存储在p
  • 迭代所有从3到结束号的奇数
  • 对于每个数字,计算其平方根并将其存储到变量中
  • 迭代p所有先前元素,直到达到除数,或者给定索引处的矢量的值从第二个元素开始达到平方根,因为对数大于2的对将被忽略
  • 如果在内部循环中发现除数,则将其存储到向量中并退出内部循环

最后,您将有一个素数vector ,索引将表示素数索引,而值将是实际素数。 每个元素都是它自己的素数。

你把号码弄乱了。 如果p[k]是数k+1的素数,则您的for循环是错误的

for(int j = i*i; j < n; j += i)

并且应该是

for(int j = (i-1)*(i-1); j < n; j += (i-1))

我的建议是使用更多信息量大的变量名,避免像p[k]这样的混淆源给出有关整数k+1

您的向量构造是错误的。 一定是

vector<bool> p(n, true); //all values set to true, from 0 to n

代替

vector<bool> p(true, n); //all values set to true, from 0 to n   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM