大范围输入的质数和

时间:2019-06-23 16:53:37

标签: javascript loops

我正在编写代码以查找给定数字以下所有素数的总和(在这种情况下,我希望找到2000000)

我的代码可以很好地运行20000以下的数字,但是当我加0时,它不会。

我试图在codeandbox上运行它,它会告诉我某处可能存在无限循环。

const isPrime = number => {

  let k=0

  for (let i=2; i < number; i++) {
    if (number % i === 0) {
    k++
    }
  }
  if (k === 0) {
    return true
  } else {
      return false
  } 
}

const sumOfPrimes = limit => {

  let primeSum = 0
  for (let i=1; i <= limit; i++) {
    if (isPrime(i)) {
        primeSum += i
    }
  } console.log(primeSum);
}

sumOfPrimes(2000000);

3 个答案:

答案 0 :(得分:2)

如果必须处理多达2,000,000的数字,那么这不是解决问题的正确方法。有许多用于确定数字是否为质数的算法,并且在算法的复杂性与大数的效率之间需要权衡。为了知道哪种算法适合您的用例,我们需要知道您的用例是什么。 (听起来您正在尝试解决课程或代码挑战中的给定问题。)

但是即使使用了所使用的算法,也有一些简单的方法可以加快它的速度。一方面,在isPrime的循环中,当number % i === 0时,您应该return false而不是增加变量并稍后对其进行检查。这种变化本身应该可以极大地加快程序运行速度,因为大多数数字的除数很小,因此大多数数字只会在该循环中运行几次。

另一种简便的加速方法是限制循环播放的数字。您正在遍历从2到n的所有数字。但是要检查数字是否为质数,只需要按质数检查其可除性。如果您的目标是计算第一个但很多质数的总和,那么这很容易:建立一个质数列表,根据列表中已有的数字检查每个新候选数。我强烈怀疑这种方法是否足够快地满足您的需求。

答案 1 :(得分:1)

更有效的方法是使用Eratosthenes筛子。通常,这将返回一个达到给定限制的素数列表,但是使用reduce进行少量修改后,您可以使其返回总和:

function sumOfPrimes(n) {
    const nums = Array(n).fill(true); 
    nums[0] = nums[1] = false;
    const sq = Math.sqrt(n);

    for (let i = 2; i <= sq; i++) {
        if (nums[i]) {
            for (let j = i * i; j < n; j += i) nums[j] = false;
        }
    }
    
    return nums.reduce((sum, a, i) => sum + (a && i), 0);
}


console.log(sumOfPrimes(10));
console.log(sumOfPrimes(2000000));

请注意,有一些方法可以获得更好的性能,例如segmented sieve of Eratosthenes

答案 2 :(得分:0)

以为我会通过一个示例实现来备份https://twitter.com/KhaosT/status/1140814602017464320

<TextView
        android:id="@+id/txtLogo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/SSA0Logo"
        android:textColor="@color/SSA0LogoText"
        android:textSize="50sp"/>

const primes = [2, 3]; function isPrime (n) { // eliminate base cases if (n < 2) return false; const sqrt = Math.sqrt(n); let i; // check if known primes are factors of n for (i of primes) { if (i > sqrt) break; if (n % i === 0) return false; } // check if odd numbers between largest // known prime and sqrt(n) are factors of n for (i += 2; i <= sqrt; i += 2) { if (n % i === 0) return false; } // prevents duplicate primes from being added if (primes[primes.length - 1] < n) { primes.push(n); } return true; } function sumOfPrimes (limit) { let primeSum = 0; for (let i = 1; i <= limit; i++) { if (isPrime(i)) primeSum += i; } return primeSum; } console.log(sumOfPrimes(10)); console.log(sumOfPrimes(2000000));是专门为增加输入isPrime()而被调用而设计的。如果在较小的素数n之前之前检查了较大的素数n,则条件

n

将无法将较小的质数添加到已知质数列表中,但是由于这种用法不会发生这种情况,因此就足够了。