当前位置: 首页 > 知识库问答 >
问题:

C:埃拉托色尼筛不总是工作

谢鸿
2023-03-14

我正在做一个C程序,用厄拉多塞筛寻找质数

目前我有以下代码:

C

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class is_multiple_of {
    int m_div;
public:
    is_multiple_of(int div) : m_div(div) {}
    bool operator()(int n) { return ((n > m_div) && (0 == n % m_div)); }
};

int main ()
{
    vector<int> v;
    for (int i=2; i<=100; i++) v.push_back(i);

    v.erase( remove_if(v.begin(), v.end(), is_multiple_of(2)), v.end() );
    v.erase( remove_if(v.begin(), v.end(), is_multiple_of(3)), v.end() ); 
    v.erase( remove_if(v.begin(), v.end(), is_multiple_of(5)), v.end() ); 
    v.erase( remove_if(v.begin(), v.end(), is_multiple_of(7)), v.end() ); 

    for (unsigned i=0; i<v.size(); ++i)
        cout << v[i] << " ";


    cout << endl << v.size();
    return 0;
}

这工作正常,即它说在1和100之间有25个素数(这是正确的)。但是,例如,如果我想知道前500个素数,它会说有118个,而实际上有95个。为了解决这个问题,我必须添加更多的倍数来删除,即v.erase(remove_if(v.begin(),v.end(),is_multiple_of(11)),v.end());,然后添加更多is_multiple_of()

有没有一种方法可以使它更有效,而不仅仅是让它去除以前发现的素数的更多倍数?

共有1个答案

申屠锦
2023-03-14

既然你想实现你的素数查找版本,那么下面的方法应该有效(我们使用的是500)

 int stopInt = static_cast<int>(sqrt(500));
 int j = 0;
 for (int i = 0; i < stopInt; ++i, ++j)
     v.erase(remove_if(v.begin(), v.end(), is_multiple_of(v[j])), v.end());

这里有一种替代方法,只需将项目移动到向量的末尾即可“标记”项目:

     vector<int>::iterator sMarked = v.end();
     int stopInt = static_cast<int>(sqrt(500));
     int j = 0;
     for (int i = 0; i < stopInt; ++i, ++j)
         sMarked = remove_if(v.begin(), sMarked, is_multiple_of(v[j]));
     v.erase(sMarked, v.end());

因此,我们通过跟踪< code>remove_if的返回值来不断标记元素。最后,我们执行一个简单的< code>vector::erase来删除多个。这应该比在循环中不断调用< code>v_erase更有效。

 类似资料:
  • 就像这个问题一样,我也在厄拉多塞的筛子上工作。同样来自《c语言编程原理和实践》一书的第4章。我能够正确地实现它,并且它的功能完全符合练习的要求。 现在,我怎样才能在输入的中处理真正的大数字?类型应该允许我输入2^32=4,294,967,296的数字。但是我不能,我运行内存溢出。是的,我已经计算过了:存储2^32量的int,每个32位。所以32/8*2^32=16 GiB的内存。我只有4 GiB…

  • 我试图找到素数使用厄拉多塞筛位数组,但我使用的是无符号整数数组。我需要能够产生多达2,147,483,647个素数。我的代码工作正常,可以生成大约10,000,000个,但是当我增加数组的大小以容纳更大的数字时,它失败了。有人能指导我如何用c语言(不是c语言)使用位向量吗?谢谢 这是我的代码:

  • 我正在尝试让我的埃拉托斯特尼筛程序仅输出用户请求的前n个素数。Sieve本身工作得很好 - 它正确地输出了前100个素数(如下面的数组所示),但是最后一个循环中的计数器变量无法正常工作,我无法找出原因。例如,如果用户输入“5”表示 n,则只会打印前 3 个定焦值。 有人可以帮我找出我的错误吗?我的目的是让“count”成为一个非常简单的计数器,每次都会增加1,直到它达到n。

  • 我正在尝试对厄拉多塞的筛子进行并行实现。我做了一个布尔列表,对于给定的大小,用true填充。无论何时发现一个素数,该素数的所有倍数在布尔列表中都被标记为假。 我试图使这个算法并行的方法是在仍然过滤初始质数的同时启动一个新线程。例如,算法从素数 = 2 开始。在 for 循环中,当素数 * 素数时,我做另一个 for 循环,其中检查素数 (2) 和素数 * 素数 (4) 之间的每个数字。如果布尔列表

  • 我有一个< code >无符号int的位数组< code>prime[]。我希望用这个数组实现一个厄拉多塞筛,让每一位代表一个数。也就是说,给定< code>n,保存对应于< code>n的位的数组元素将是< code>prime[n/32],并且特定位将在位置< code>n2中。 我的函数在数字为素数时返回1(如果其位==0),否则返回0: 我的< code>setBit(int n)函数只是

  • 所以我的代码需要帮助。由于某种原因,当我输入超过500,000的数字时,它总是崩溃。这是确切的分配。 实现埃拉托斯特尼筛,并用它来查找所有小于或等于一百万的素数。使用结果来证明哥德巴赫猜想对于 400 万到 100 万之间的所有偶数(包括 100 万)。 使用以下声明实现函数: 此函数采用整数数组作为其参数。数组应初始化为值 1 到 1000000。该函数修改数组,以便仅保留质数;所有其他值均归零