我正在尝试用C ++实现Erasthones的Sieve,我遇到了很多问题。我的代码如下:
#include <iostream>
int main()
{
const int max = 1000;
int count = 1;
bool arr[max];
for(int i = 0; i < max; ++i)
arr[i] = true;
for(int i = 2; i < max; i++)
{
//mark all multiples
for(int j = 2; (j*i) < max-1; ++j) arr[i*j] = false;
}
}
我不知道下一步是什么。我看过网上但我不了解很多代码。能否请您提供一个工作c ++代码及其工作原理的示例?
答案 0 :(得分:2)
你的代码中没有重大缺陷 - 它有效,但它有点笨重。
基本逻辑是:
sieve
的向量填充为1(用于节省内存的字符)retVector
的第一个向量中,并返回所有素数的向量,直到limit
c ++中筛选器的另一个工作实现可能如下所示:
vector<long long> sieve(unsigned long long & limit)
{
vector<char> sieve(limit, '1');
vector<long long> retVector;
for (long long i = 0; i < limit; i++)
sieve[i] = 1;
for (long long i = 2; i < limit; i++) {
if (sieve[i] == 1) {
for (long long j = i*i; j < limit; j += i)
sieve[j] = 0;
}
}
for (long long i = 2; i < limit; ++i) if (sieve[i] == 1) retVector.push_back(i);
return retVector;
}
答案 1 :(得分:0)
您的代码没有真的错误 - 它确实有效。它不是最好的实现,但如果您几乎没有经验编码,这是一个良好的开端,所以恭喜!
要查看您的代码是否有效,只需添加另一个打印素数的循环:
int main()
{
const int max = 1000;
int count = 1;
bool arr[max];
for(int i = 0; i < max; ++i)
arr[i] = true;
for(int i = 2; i < max; i++)
{
//mark all multiples
for(int j = 2; (j*i) < max-1; ++j) arr[i*j] = false;
}
for (int i = 2; i < max; ++i)
if (arr[i])
cout << i << " ";
}
您的代码的作用:
它会初始化一个大小为arr
的数组max
,如果arr[i] == true
是素数,则在算法执行结束时会有i
数字和arr[i] == false
否则;
您的算法首先假设每个数字都是素数。然后,它开始通过将每个数字2, 3, 4, 5, 6, ...
的倍数设置为不是素数来纠正这个假设:这是正确的,因为除1之外的任何数字的任何倍数都不能是素数(因为它可以被该数字整除) )。
您的代码和算法可以通过多种方式得到改进:
只将素数的倍数标记为不是素数,因为另一个素数已经被标记过了。这将使您的计划更有效率;
使用bitset;
从素数的平方开始标记倍数;
将2
视为边缘情况,因为它是唯一的素数。然后,您可以开始从3
开始迭代数字,并以2
:3, 5, 7, 9, ...
为增量。