JavaScript 范围内素数计数程序


素数是指恰好只有两个因数的数。我们将介绍两种在给定范围内查找素数个数的方法。第一种是使用暴力法,这种方法的时间复杂度较高。然后我们将改进这种方法,并采用埃拉托斯特尼筛法来获得更好的时间复杂度。在本文中,我们将使用 JavaScript 编程语言来查找给定范围内素数的总数。

暴力法

在这种方法中,我们将首先学习如何判断一个数是否是素数,我们可以用两种方法来实现。一种方法的时间复杂度为 O(N),另一种方法的时间复杂度为 O(sqrt(N))。

判断一个数是否为素数的直接方法

示例

首先,我们将遍历一个循环直到该数,并计算可以完美整除该数的数的个数,如果可以整除该数的数的个数不等于 2,则该数不是素数,否则该数是素数。让我们看看代码:

function isPrime(number){
   var count = 0;
   for(var i = 1;i<=number;i++)    {
      if(number%i == 0){
         count = count + 1;
      }
   }
   if(count == 2){
      return true;
   }
   else{
      return false;
   }
}

// checking if 13 and 14 are prime numbers or not 
if(isPrime(13)){
   console.log("13 is the Prime number");
}
else{    
   console.log("13 is not a Prime number")
}

if(isPrime(14)){
   console.log("14 is the Prime number");
}
else{
   console.log("14 is not a Prime number")
}

在上面的代码中,我们从 1 到 number(即我们可以找到可以整除给定数的数的范围)进行遍历,并计算出可以整除给定数的数的个数,并根据该个数打印结果。

上述代码的时间复杂度为 O(N),而检查每个数是否为素数则需要 O(N*N),这意味着这不是一个好的检查方法。

数学方法

我们知道,当一个数完美地整除另一个数时,商也是一个完美的整数,即如果一个数 p 可以被一个数 q 完美整除,商为 r,则 q * r = p。同样,r 也能完美地整除数 p,商为 q。因此,这意味着完美的因数总是成对出现的。

示例

根据上述讨论,我们可以得出结论,如果我们只检查最多到 N 的平方根的数的除法,那么它将在更短的时间内给出相同的结果。让我们看看上面方法的代码:

function isPrime(number){
   if(number == 1) return false
   var count = 0;
   for(var i = 1;i*i<=number;i++){
      if(number%i == 0){
         count = count + 2;
      }
   }
   if(count == 2){
      return true;
   }
   else{
      return false;
   }
}
// checking if 67 and 99 are prime numbers or not 
if(isPrime(67)){
   console.log("67 is the Prime number");
}
else{
   console.log("67 is not a Prime number")
}
if(isPrime(99)){
   console.log("99 is the Prime number");
}
else{
   console.log("99 is not a Prime number")
}

在上面的代码中,我们只是更改了 for 循环的范围,现在它只检查最多到 N 的平方根的元素,并将计数增加了 2。

上述代码的时间复杂度为 O(sqrt(N)),这更好,这意味着我们可以使用这种方法来查找给定范围内存在的素数个数。

L 到 R 范围内的素数个数

示例

我们只需在该范围内实现前面给出的代码,并计算给定范围内素数的个数。让我们实现代码:

function isPrime(number){
   if(number == 1) return false
   var count = 0;
   for(var i = 1;i*i<=number;i++)    {
      if(number%i == 0){
         count = count + 2;
      }
   }
   if(count == 2){
      return true;
   }
   else{
      return false;
   }
}
var L = 10
var R = 5000
var count = 0
for(var i = L; i <= R; i++){
   if(isPrime(i)){
      count = count + 1;
   }
}
console.log(" The number of Prime Numbers in the given Range is: " + count);

在上面的代码中,我们使用 for 循环遍历了从 L 到 R 的范围,并在每次迭代中检查当前数字是否为素数。如果该数字是素数,则我们将计数增加 1,最后打印该值。

上述代码的时间复杂度为 O(N*N),其中 N 是范围内的元素个数。

埃拉托斯特尼筛法

示例

埃拉托斯特尼筛法以一种高效的方式工作,并在 O(Nlog(log(N))) 时间内找到给定范围内的素数个数,这比其他算法快得多。筛法占用的空间为 O(N),但这并不重要,因为时间效率很高。让我们看看代码,然后我们将解释代码:

var L = 10
var R = 5000
var arr = Array.apply(null, Array(R+1)).map(Number.prototype.valueOf,1);
arr[0] = 0
arr[1] = 0

for(var i = 2;i<=R;i++){
   if(arr[i] == 0){
      continue;
   }
   for(var j = 2; i*j <= R; j++){
      arr[i*j] = 0;
   }
}

var pre = Array.apply(null, Array(R+1)).map(Number.prototype.valueOf,0);
for(var i = 1; i<= R;i++){
   pre[i] = pre[i-1] + arr[i];
}
answer = pre[R]-pre[L-1]
console.log("The number of Prime Numbers in the given Range is: " + answer);

在上面的代码中,我们看到了埃拉托斯特尼筛法的实现。首先,我们创建了一个大小为 R 的包含 1 的数组,之后我们使用 for 循环遍历该数组,对于每次迭代,如果当前数字不为 1,则它不是素数,否则它是素数,并且我们已经删除了所有小于 R 且是当前素数倍数的数字。然后我们创建了一个前缀数组,它将存储从 0 到当前索引的素数个数,并且可以在常数时间内提供从 0 到 R 的每个查询的答案。

时间和空间复杂度

上述代码的时间复杂度为 O(N*log(log(N))),这比 O(N*N) 和 O(N*(sqrt(N))) 好得多。上述代码的空间复杂度比以前的代码更高,为 O(N)。

结论

在本教程中,我们学习了如何使用 JavaScript 编程语言在给定范围内查找素数的个数。素数是指恰好只有两个因数的数。1 不是素数,因为它只有一个完美的除数。我们已经看到了三种方法,其时间复杂度分别为 O(N*N)、O(N*sqrt(N)) 和 O(N*log(log(N)))。此外,前两种方法的空间复杂度为 O(1),而埃拉托斯特尼筛法的空间复杂度为 O(N)。

更新于:2023年3月24日

4K+ 浏览量

开启您的职业生涯

完成课程获得认证

开始
广告