Eratosthenes的筛子 - 从矢量中移除非素数

时间:2014-08-23 09:17:37

标签: c++ sieve-of-eratosthenes

我正在尝试使这个程序工作:

int main()
{
    // prompt user for max number
    // ...

    // generate vector containing all numbers from 2 up to max
    // ...

    // give value 1 to not-prime numbers
    // ...

    // remove all not-prime numbers with value 1
    // ...

    // print out all numbers (all remaining are prime)
    // ...
}

一切都很好,除了我需要识别素数并将其值改为1的步骤。我尝试了一切,我真的没有想法。这是我对该代码块的最后一个想法:

// give value 1 to not-prime numbers
for (int i = 2; i < int(sqrt(max)); i++)
{
    for (int j = 0; j < numbers.size(); j++)
    {
        numbers[numbers[j] * i - 2] = 1;
    }
}

,显然它不起作用。救命啊!

2 个答案:

答案 0 :(得分:0)

您应该显示更多代码,以便我们使用您的工具。例如,numbers的类型是什么?如果您确实使用的是C ++,则可能是std::arraystd::vector。为了方便起见,我假设你想使用std::vector。此外,你不应该像这样使用C风格的演员:int(sqrt(max))

所以,这就是我要做的事情:
首先,创建一个布尔值向量,其中包含从0max的所有索引。索引表示筛子中的数字,如果该数字是素数,则布尔值指出。首先,您需要假设所有数字都是素数,因此您使用true初始化矢量。

std::vector<bool> sieve(max+1, true); // Sets every value to true

为方便起见,我在筛子中包含0和1,但您可以在代码中的任何位置使用index-2。只是为了进行设置,我需要将false放在这里:

sieve[0] = sieve[1] = false;

然后,您想继续使用筛选算法。

int limit = static_cast<int>(sqrt(max));
for (int i = 2; i < limit; ++i)
{
    // If i is a prime, proceed with multiples
    if (sieve[i])
    {
        // Here, i*j is a multiple of i, hence not a prime (except when j = 1)
        for (int j = 2; i*j <= max; ++j)
        {
            sieve[i*j] = false;
        }
    }
}

您也可以将其用作内循环:

for (int j = 2*i; j <= max; j += i)
{
    sieve[j] = false;
}

现在,您的筛选已完成:每个具有相应true值的索引都是素数,您只需要打印它们!您可以将它们复制到另一个向量中,然后打印出最后一个向量,直接打印对应于素数的索引。

答案 1 :(得分:0)

我假设number是一个包含2到max(number [0] = 2)

的数字的向量

你的循环应该是:

// give value 1 to not-prime numbers
for (int i = 2; i < int(sqrt(max)); i++) // ok i are true numbers starting at 2
{
    for (int j = (i * i) - 2; j < numbers.size(); j + = i) // j are indices for numbers starting at i * i (i*j for j< i already seen) stepping by i
    {
        numbers[j] = 1; // as j as indices do it directly
    }
}

还有什么可写的:

// give value 1 to not-prime numbers
for (int i = 2; i < int(sqrt(max)); i++) // ok i are true numbers starting at 2
{
    for (int 0 = (i * i); j < max; j + = i) // j are true numbers starting at i * i (i*j for j< i already seen) stepping by i
    {
        numbers[j] = 1; // index for j is j-2
    }
}