【问题标题】:I read about the Sieve of Eratosthenes yesterday and wanted to implement it昨天我读到了关于 Eratosthenes 的筛子,并想实施它
【发布时间】:2014-03-31 21:47:43
【问题描述】:

我正在寻找有关我的算法实现的一些反馈。我该如何改进它?由于整数溢出,我在计算大于 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;
}

【问题讨论】:

  • 这个问题似乎是题外话,因为它是关于审查(工作?)代码。
  • stackoverflow 适用于有 bug 的代码,但请务必解释您遇到的问题,因为人们不喜欢只进行编码转储和猜测。
  • 在codereview.SE试试,他们更偏向于这类问题。
  • 另请注意,有一个 codereview.stackexchange.com 用于工作代码,您希望获得审查和改进建议。

标签: c++ sieve-of-eratosthenes


【解决方案1】:

您正在访问超出范围的数组:

bool * prime = new bool[CAP];

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

您应该将其更改为使用&lt; 而不是&lt;=

请注意,这同样适用于其他循环中的 &lt;=。

【讨论】:

  • 我已经进行了这些更改。谢谢!
【解决方案2】:

除了修复数组越界错误之外,您还可以做一些提高效率的事情(使用 i

此外,你的内部 for 循环(以 j 作为变量)做了一些它不需要的额外工作;而不是检查每个 j 的 j % i == 0,只需将 j++ 替换为 j += i,这样 j 将始终可以被 i 整除。较小的优化是更改外部循环的边界( i

【讨论】:

    【解决方案3】:

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

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

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

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

    所以第一个就变成了

    if (prime[i]) {
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-15
      • 1970-01-01
      • 2010-09-13
      • 2022-01-08
      • 2011-09-26
      • 1970-01-01
      相关资源
      最近更新 更多