我昨天读到了关于Eratosthenes的Sieve并希望实现它

时间:2014-03-31 21:47:44

标签: c++ sieve-of-eratosthenes

我正在寻找关于我的算法实现的一些反馈。我怎样才能改进它?我在计算较大的素数时遇到了问题> 46349由于整数溢出,但通过使用sqrt而不是pow来修复它。

#include<iostream>
#include<math.h>
using namespace std;

int main(){
    int number;
    cin >> number;
    const int CAP = number;
    bool * prime = new bool[CAP];

    for(int i = 0; i <= CAP; i++){ //sets all to true for the marking
        prime[i] = true;
    }

    for(int i = 2; i <= number; i++){
        if(i <= sqrt(number) && prime[i] == true){
            for(int j = i*i; j <=number; j++){ //if %i == 0 mark false
                if(j % i == 0){               //haven't tried another way
                    prime[j] = false;
                }
            }
        }
    }

    for(int i = 2; i <= number; i++){
        if(prime[i] == true){
            cout << i << endl;
        }
    }

    return 0;
}

3 个答案:

答案 0 :(得分:1)

您正在以下地址访问数组:

bool * prime = new bool[CAP];

for(int i = 0; i <= CAP; i++)

您应该将其更改为使用<而不是<=

请注意,这同样适用于其他循环中的<=

答案 1 :(得分:0)

你可以做一些有效的事情,除了修复你将在所有循环中获得的数组之外的错误(使用i&lt; length,而不是i&lt; = length)。例如,您可以在数组上使用memset将其中的所有内容设置为true。

此外,你的内部for循环(以j作为变量)做了它不需要的额外的东西;而不是检查每个j是否j%i == 0,只需用j + = i替换j ++,所以j总是可以被i整除。较小的优化是更改外循环的界限(i <= sqrt(数字),因此您不需要在内循环之前使用if语句。

答案 2 :(得分:0)

您实际上可以完全取消sqrt。你有:

if(i <= sqrt(number) && prime[i] == true) {

但下一行的第一个条件是多余的,其中i*inumber进行比较。

   for(int j = i*i; j <= number; j++) {

所以第一个变成了

if (prime[i]) {