我正在制作一个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_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个素数(即correct)。但是,如果我想知道前500个素数,例如,它会说有118个实际上有95个。要纠正这个问题,我必须添加更多倍数来移除ie v.erase( remove_if(v.begin(), v.end(), is_multiple_of(11)), v.end() );
然后添加更多is_multiple_of()
的。
有没有办法让它更有效率,而不仅仅是让它删除更多的先前找到的素数?
答案 0 :(得分:1)
由于您要实现查找素数的版本,因此以下内容应该有效(我们使用的是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());
以下是#34;标记&#34;只需将它们移动到向量的末尾即可:
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());
因此,我们通过跟踪remove_if
的返回值来不断标记元素。然后在最后,我们做一个单vector::erase
来删除倍数。这应该比在循环中不断调用v_erase
更有效。