【问题标题】:Chain of Sieves to generate prime numbers C++生成素数 C++ 的筛链
【发布时间】:2015-05-07 00:19:32
【问题描述】:

我正在尝试将找到的每个质数输入到“筛子”对象链中。下面的代码实现了我最终想要做的事情,但是每个筛子(素数)类都是手动实现的(检查后续数字是否可以被存储的素数整除,然后它们应该被丢弃,否则它们应该被转发到下一个筛子链),有没有一种方法可以动态地做到这一点,即每次找到一个新的素数时,我都必须创建一个筛子对象。非常感谢任何帮助。

#include <iostream>
#include <stdio.h>

using namespace std;

class Sieve
{
public:
    virtual int NextNumber () = 0;
};

class SourceSieve: public Sieve
{
public:
    SourceSieve () : _i (2) {}
    int NextNumber ();
private:
    int _i;
};

class Sieve2: public Sieve
{
public:
    Sieve2 (Sieve & src) : _src (src) { }
    int NextNumber ();
private:
    Sieve & _src;
};

class Sieve3: public Sieve
{
public:
    Sieve3 (Sieve & src) : _src (src) {}
    int NextNumber ();
private:
    Sieve & _src;
};

class Sieve5: public Sieve
{
public:
    Sieve5 (Sieve & src) : _src (src) {}
    int NextNumber ();
private:
    Sieve & _src;
};

class Sieve7: public Sieve
{
public:
    Sieve7 (Sieve & src) : _src (src) {}
    int NextNumber ();
private:
    Sieve & _src;
};
//Here's the implementation of NextNumber for SourceSieve and Sieve2:
int SourceSieve::NextNumber ()
{
    if (_i > 100)
        return -1; // end
    return _i++;
}

int Sieve2::NextNumber ()
{
    int i;
    do
    {
        i = _src.NextNumber ();
    } while (i % 2 == 0 && i != 2 && i != -1);
    return i;
}

int Sieve3::NextNumber ()
{
    int i;
    do
    {
        i = _src.NextNumber ();
    } while (i % 3 == 0 && i != 3 && i != -1);
    return i;
}

int Sieve5::NextNumber ()
{
    int i;
    do
    {
        i = _src.NextNumber ();
    } while (i % 5 == 0 && i != 5 && i != -1);
    return i;
}
int Sieve7::NextNumber ()
{
    int i;
    do
    {
        i = _src.NextNumber ();
    } while (i % 7 == 0 && i != 7 && i != -1);
    return i;
}


int main ()
{
    SourceSieve src;
    Sieve2 s2(src);
    Sieve3 s3 (s2);
    Sieve5 s5 (s3);
    Sieve7 s7 (s5);

    int i = 1;
    for (;;)
    {

        i = s7.NextNumber();
        if (i == -1)
            break;
        std::cout << i <<" ";


    }
}

【问题讨论】:

  • 我想以某种方式帮助您,但不能,因为多次重新阅读您的问题,仍然无法理解您编写此代码的原因。也许提供一些没有代码的例子会更好,只是在文本中,逐个动作。
  • 如何创建 1 个 Sieve 类来获取前一个(可能还有一个数字来跟踪您需要的素数)?您可以在列表中跟踪它吗?
  • 我的主要任务是生成从 2 开始的数字并输入到“筛子”对象链中。每个筛子都应该存储它收到的第一个数字(质数)并打印出来。然后应检查后续数字是否可被该素数整除。如果随后的数字可以被存储的素数整除,那么它们应该被丢弃,否则它们应该被转发到链中的下一个筛子。我需要在 C++ 中做这样的事情:link
  • 为什么不这样做类似于:primesieve.org/segmented_sieve.html

标签: c++ primes sieve


【解决方案1】:

如果我理解你的问题,你可以用这个替换你所有的Sieve2Sieve3,...类:

class PrimeSieve : public Sieve
{
public:
  PrimeSieve(Sieve& src, int prime)
  : Sieve()
  , src_(src)
  , prime_(prime) {
  }

  override int NextNumber () {
    int i;
    do
    {
      i = _src.NextNumber ();
    } while (i % 2 == 0 && i != 2 && i != -1);
    return i;
  }

private:
  Sieve & src_;
  int prime_;
};

那么,您的调用代码将是:

int main ()
{
  SourceSieve src;
  vector<PrimeSieve> sieves;
  sieves.emplace_back(src, 2);

  int i = 1;
  for (;;)
  {
    auto& currentLastSieve = sieves.back();
    i = currentLastSieve.NextNumber();
    if (i == -1)
      break;
    sieves.emplace_back(currentLastSieve. i);
    std::cout << i <<" ";
  }
}

但是,我宁愿将排序逻辑放在您的 Sieve 类之外,并放入更容易推理的东西中,例如外部容器。

【讨论】:

  • 没错,我也不想手动创建 PrimeSieve 对象,而是在找到新的素数时动态创建它们。
  • 我添加了那部分,再次假设我理解正确
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
相关资源
最近更新 更多