C++;:埃拉托斯烯的筛不总是起作用 我用C++程序编写了一个用< < p> >求素数的C++程序。
目前我有以下代码: C++C++;:埃拉托斯烯的筛不总是起作用 我用C++程序编写了一个用< < p> >求素数的C++程序。,c++,sieve-of-eratosthenes,C++,Sieve Of Eratosthenes,目前我有以下代码: 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_
#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;
}
#包括
#包括
#包括)。然而,如果我想知道前500个素数,例如,它会说有118个,而实际上有95个。为了纠正这个问题,我必须添加更多的倍数来删除,即v.erase(如果(v.begin(),v.end(),是(11)的倍数),v.end(),则删除)然后添加更多的是()的倍数
有没有一种方法可以让它更有效,而不仅仅是让它删除以前找到的素数的倍数?既然您想实现查找素数的版本,那么下面的方法应该可以工作(我们使用500)
intstopint=static_cast(sqrt(500));
int j=0;
对于(int i=0;i
这里有一种替代方法,通过将项目移动到向量的末尾来“标记”项目:
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());
vector::迭代器sMarked=v.end();
int stopInt=静态_铸造(sqrt(500));
int j=0;
对于(int i=0;i
因此,我们通过跟踪remove\u if
的返回值来不断标记元素。然后在最后,我们执行一个vector::erase
来删除倍数。这应该比在循环中不断调用v_erase
更有效。您的代码是如何实现Eratosthenes筛选的(如wiki链接中所述)?它删除所有2的倍数(evens),然后删除所有3的倍数,然后是5,然后是7,然后是11(您知道这是怎么回事)@Bijan你在哪里删除11的倍数?我知道你的代码是怎么做的,但是它没有实现Eratosthenes的筛选。要使筛选有效,你必须删除所有的素数,直到sqrt(n)
。对于n==100
这是10,但是对于n==500
这是19。
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());