【问题标题】:Implementing a prime number counter实现质数计数器
【发布时间】:2015-06-11 14:38:01
【问题描述】:

由于某种原因,我的最后一个素数(int prime)没有出现在最后。有什么线索吗? fyi:primeEval 代表一个标志,如果循环结束 && primeEval==2,则该数字实际上是一个素数。 qty 代表素数的数量。

int main(){


long primeEval=0,prime=0,qtyprime=0;

time_t timerr=(time(NULL)+10);



   for (int i = 2; time(NULL)!=timerr; i++) {

        for (int j = 1; j <= i; j++) {

            if((i%j)==0 && primeEval<2){

                primeEval++;

                if (i==j && primeEval==2) {
                    qtyprime++;
                    prime=i;
                    primeEval=0; // Resets for the next number 'i'

                }
            }

        }
    }

cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}

【问题讨论】:

  • 您可以通过将j &lt;= i 更改为j &lt;= sqrt(i) 轻松提高性能。这将强制执行更多更改,但运行速度会更快
  • 没有显示是什么意思?好像是给错了号码?根本不打印?
  • @OlivierPoulin 输出为:找到的最后一个素数:2 找到的总素数:45190040
  • 另外,一旦你找到了一个数字y=i%j,为什么还要继续内循环呢?立即完成并继续下一个数字。
  • @shapiro.yaacov 是一个素数,只能被它自己和 1 整除,primeEval 得到 2 个标志来表明它是素数。

标签: c++ algorithm math primes


【解决方案1】:

新答案:

随着代码的更改,您现在将遍历所有数字。现在的问题是,一旦找到非质数,您将永远不会重置primeEval,因此您将永远不会捕获另一个质数如果您将代码更改为以下代码,它将起作用

int main()
{
    long primeEval = 0, prime = 0, qtyprime = 0;
    time_t timerr = (time(NULL) + 10);

    for (int i = 2; time(NULL) != timerr; i++) {

        for (int j = 1; j <= i; j++) {

            if ((i%j) == 0){
                primeEval++;  // incmrent factor
            }
            // if we are at the end and have 2 factors then we are prime
            if (i == j && primeEval == 2) {
                qtyprime++;
                prime = i;
                primeEval = 0; // Resets for the next number 'i'
            }
            // if we reach the end with more than 2 factors reset and go to the next number
            if (i == j && primeEval > 2) {
                primeEval = 0; // Resets for the next number 'i'
            }
        }
    }
    cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
    cin.get();
    return 0;
}

我还建议您查看Which is the fastest algorithm to find prime numbers? 以找到一些更有效的获取素数的方法。

旧答案:

在您的代码中:

for (int i = 2; time(NULL)!=timerr; i=+2)

因此,当您从素数开始检查时,您会从 2 开始,它是素数。然后你将i 增加 2,所以你检查的下一个数字是 4,它是一个偶数。除了 2,所有偶数都不是素数。因为你总是加 2,所以你总是有一个偶数,所以你会找到的唯一素数是 2。

【讨论】:

  • 这是一个旧的实现(只检查奇数),我忘了更正,但它是 i++ 而不是 i+2。
  • @sayajeans 修复了吗?
  • “然后你将 i 增加 2,所以你检查的下一个数字是 4,这是一个偶数”:现在 OP 已经解释这是一个错字,他想写 i++,但因为他写了+= 而不是 =+,实际上他每次都将 i 设置为 +2。
  • 啊,该死的错别字!我的意思是:他写的是=+而不是+=
【解决方案2】:

你有不同的问题:

for (int i = 2; time(NULL)!=timerr; i=+2) {

这里的语法是错误的:它必须是i+=2,而不是i=+2,否则你会一直将i设置为+2并测试2是否是素数。

那么,正如其他人所指出的,你为什么将i 增加 2?如果要优化搜索,应该将j 增加2,而不是i!并且 j 在任何情况下都应该从 2 开始(或者,根据你的方法,从 1 开始),然后你应该尝试 j = 3,然后你可以将 j 增加 2,而不会跳过一些重要的除数。

然后,只有在找到素数时才将 primeEval 重置为 0。如果你测试一个不是素数的数字i,primeEval 保持在 2,你将永远不会再次进入该块。

所以最终的代码可能是:

#include <iostream>
using namespace std;

int main(){

    long primeEval=0,prime=0,qtyprime=0;

    time_t timerr=(time(NULL)+10);

    for (int i = 2; time(NULL)!=timerr; i++) {
        primeEval=0;
        for (int j = 1; j <= i; j++) {
            if((i%j)==0 && primeEval<2){
                primeEval++;
                if (i==j && primeEval==2) {
                    qtyprime++;
                    prime=i;
                    primeEval=0; // Resets for the next number 'i'
                }
            }
        }
    }

    cout << "last prime found: " << prime << endl << "Ttal primes found: " << qtyprime;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-11
    • 2023-03-24
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多