【问题标题】:Sieve of Eratosthenes - Removing non-prime from vector埃拉托色尼筛 - 从向量中去除非素数
【发布时间】:2014-10-17 02:19:52
【问题描述】:

我正在努力使这个程序工作:

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;
    }
}

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

【问题讨论】:

  • 不确定我是否在关注您,在Sieve of Eratosthenes 中,您首先假设所有数字都是素数,并丢弃发现为非素数的数字。此外,对于更高效的代码 - 如果 numbers[i] 不是素数,则需要终止内部循环的 if 条件。
  • o_O ?你说你将非素数设置为 1,然后你说你想将素数设置为 1……它是什么? :)
  • 我想消除所有非质数,这只是向您展示我的想法的一些不成功的尝试。

标签: c++ sieve-of-eratosthenes


【解决方案1】:

我假设 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
    }
}

【讨论】:

  • 这可行,并为所有非质数提供适当的值 1。谢谢!
【解决方案2】:

您应该显示更多代码,以便我们使用您的工具。例如,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 值的索引都是质数,你只需要打印它们!您可以将它们复制到另一个向量中,然后打印出最后一个向量,或者直接打印与素数对应的索引。

【讨论】:

    猜你喜欢
    • 2011-12-16
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多