埃拉托色尼筛法 C++ 无限循环

Sieve of Eratosthenes C++ Infinite Loop

所以,为了我自己的利益,我一直在解决 Bjarne Stroustrup 的编程:使用 C++ 的原则和实践中的一个问题,这个问题已经困扰我几天了。

我应该使用第 4 章中学到的工具(不是很多)来实现经典的埃拉托色尼筛法算法,这就是我目前所拥有的:

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

int main()
{
    int p = 2;
    int n = 0;
    vector<int> nums{ 1, 1 };

    cout << "Enter an integer greater than 1:\n";
    cin >> n;

    for (int i = 2; i <= n; ++i)
        nums.push_back(0);

    while (p < sqrt(n))
    {
        for (int i = 2; (i*p) <= n; ++i)
        {
            nums[i*p] = 1;
        }

        for (int i = (p+1); i <= n; ++i)
        {
            if (nums[i] == 0)
            {
                p = i;
                break;
            }
        }
    }

    for (int i = 0; i <= n; ++i)
    {
        if (nums[i] == 0)
            cout << i << '\n';
    }

    return 0;
}

此代码非常接近工作但没有雪茄。它只打印 5 之后的质数,包括 5,它不打印 2 或 3。我知道问题是由于我的标记循环标记了 nums[2] 和 nums[3],所以我尝试添加以下代码行确保 2 和 3 未被标记,因为它们被用作 p 起始值:

nums[p] = 0;

我将该行放在嵌套在 while 循环中的两个 for 循环之间。我不知道如何解决,但这不知何故导致了我已经尝试了几个小时来修复的无限循环。我真的无计可施了。

注意:我一直在用 n = 23 测试这个。

因此,在确定第一个循环起点后,问题是下一个循环。

因为下一个循环总是从0开始寻找下一个素数,所以它总是会找到2,这将导致无限循环。

要解决此问题,请从上一个值开始搜索下一个素数:

    for(int i = p + 1; i <= n; ++i)