Eratosthenes c和x2B的筛+;实现错误 我在C++中写了埃拉托色尼的筛选器的实现,但是每当代码达到59(第十六素数)时,它就停止工作。在我的旧机器上只能达到37。当我调试程序时,所有变量似乎都工作正常;程序只是崩溃了。这是:(我知道它有很多评论,很多是不必要的。)

Eratosthenes c和x2B的筛+;实现错误 我在C++中写了埃拉托色尼的筛选器的实现,但是每当代码达到59(第十六素数)时,它就停止工作。在我的旧机器上只能达到37。当我调试程序时,所有变量似乎都工作正常;程序只是崩溃了。这是:(我知道它有很多评论,很多是不必要的。),c++,visual-studio-2010,C++,Visual Studio 2010,尽管调试返回(gasp)堆溢出,但运行编译版本不会返回。编译后的版本在104759处停止,超过1。这可能很容易解决。但是程序不会打印最后一位,它会在最后一位为您提供解决方案。奇怪 int number_of_primes = 1; //we know the first prime -- 2 long long *primes = new long long [number_of_primes]; 这将创建一个单元素数组。我很确定你需要比这更大的东西来储存素数 具体来说,一

尽管调试返回(gasp)堆溢出,但运行编译版本不会返回。编译后的版本在104759处停止,超过1。这可能很容易解决。但是程序不会打印最后一位,它会在最后一位为您提供解决方案。奇怪

int number_of_primes = 1;           //we know the first prime -- 2
long long *primes = new long long [number_of_primes];
这将创建一个单元素数组。我很确定你需要比这更大的东西来储存素数

具体来说,一旦您开始设置诸如
primes[11]
(例如)之类的值,您就进入了未定义行为的领域

也许有一个不同的变量,你可以考虑使用在<代码>中的大小<新>代码>声明,轻推,轻推,眨眼,眨眼,点头就像眨眼对一匹瞎马一样:-)


代码中还有一些其他问题。最主要的一点是,你的筛子本身只有10000个元素长。筛子的概念是,你取大量的东西,过滤掉那些不匹配的东西。值得一提的是,10001是105000以下,所以你的筛子至少应该有那么大

其次,我看到人们使用数字的平方来优化因子的发现,但不是这样:

for (long long j=current_sieve*current_sieve; j <= sieve_size; j++)
    if (j%current_sieve == 0) sieve[j] = 1;

for(long long j=current_sieve*current_sieve;j这里有一个固定版本可供比较:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    const int sieve_size = 1 << 20;
    const int solution_number = 10001;
    int number_of_primes = 0;
    vector<bool> sieve(sieve_size, true);

    for (int i = 2; i < sieve_size; i++)
    {
        if (!sieve[i])
            continue;

        if (++number_of_primes == solution_number)
        {
            cout << "The 10 001st prime number is:" << i << endl;
            return 0;
        }

        for (long long j = i*2; j < sieve_size; j += i)
            sieve[j] = false;
    }
}

谢谢你的快速回答!我会试试:)是的,也是。我改变了筛子的大小,以便更容易地调试,并且很快就忘记了。我认为我的优化仍然有效,但效率不高。。。无论如何,我用我的新代码更新了我的帖子。@Ernest3.14,无论从n^2开始而不是从2n开始,你可能会得到什么改进(我并不完全相信这会起作用,但我还没有找到一个反例,所以你可能是对的),都会被你的循环添加一个并检查每个数字的事实彻底抹杀。您可以只添加curr_sv而不选中:
(a+1)n=an+n
.Duh。这是有道理的。还有其他的优化吗(以防我需要找到很多素数)?对于很多素数,是的,但我说的很多。e-sieve可以轻松处理大量数据。除此之外,a筛(阿特金)可能更好。除此之外,我最喜欢的是pax筛::-)只需注意:那不是埃拉托斯坦筛。检查从p²开始的每个数字是否被p整除:
如果(j%current\u sieve==0)sieve[j]=1,这是审判庭。@DanielFischer哦,好吧。成功了你能用C++来检查C++中的可分割性吗?我知道对于像9或11这样的数字有一些整除技巧,但对于较大的素数来说……当然它是有效的,只是速度较慢。埃拉托斯特尼斯筛子的诀窍是根本不检查整除性。当你在你的筛子里找到一个素数时,你可以通过将索引增加
p
来划掉这个倍数(mult=p*p;mult不是很好的形式发布家庭作业或Euler问题的完整解决方案,重点是在这些情况下提供指导,而不是为他们做工作:-)@paxdiablo:老实说,给他一个可供比较的工作版本比反向工程他的解决方案更快。总比没有好。如果他在不理解的情况下一字不差地交出来,他就走不了多远了。@user1131467因为对于Project Euler问题,你所要提交的只是答案,即使你答案的最后一行也足以让OP走得更远。不过,我真的很喜欢弄清楚,;)
for (long long j=current_sieve*current_sieve; j <= sieve_size; j++)
    if (j%current_sieve == 0) sieve[j] = 1;
for (long long j = current_sieve * 2; j < sieve_size; j += current_sieve)
    sieve[j] = 1;
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    const int sieve_size = 1 << 20;
    const int solution_number = 10001;
    int number_of_primes = 0;
    vector<bool> sieve(sieve_size, true);

    for (int i = 2; i < sieve_size; i++)
    {
        if (!sieve[i])
            continue;

        if (++number_of_primes == solution_number)
        {
            cout << "The 10 001st prime number is:" << i << endl;
            return 0;
        }

        for (long long j = i*2; j < sieve_size; j += i)
            sieve[j] = false;
    }
}
The 10 001st prime number is:104743