JavaScript Prime检查程序无法正常工作

时间:2017-11-02 15:21:17

标签: javascript arrays for-loop while-loop

我的主要检查工作无效。我认为有更简单的方法来应对这一挑战,但我需要的功能是:

对于给定的数字p:

1)使用从2到p

的数字填充数组numArray

我通过以下方式实现了这一目标:

for (var i=2; i<(p + 1); i++) {
    numArray.push(i);
  };

2)虽然numArray不为空:

  • 将numArray中的第一个数字'prime'添加到数组primeArray

  • 拼接numArray的每个倍数

我的代码不使用while循环,因为我不确定如何使用一个迭代数组,但for循环也不起作用?

CAN人员只是回应了建议,而不是完全修复。绝对请不要写完整的代码来查找素数。我更有兴趣知道如何根据数组的元素迭代我继续切片的数组,以及关于如何构造我的代码的任何其他指针。

我也很困惑为什么

(numArray[k] % prime == 0)

似乎错过了数字?

function checkIfPrime(p) {
  numArray = [];
  primeArray = [];

  for (var i = 2; i < (p + 1); i++) {
    numArray.push(i);
  };

  for (var j = 0; j < numArray.length; j++) {
    if (primeArray.indexOf(numArray[j]) === -1) { //if numArray of j is not already in primeArray

      var prime = numArray[j];
      console.log(prime + " is not in numArray")

      primeArray.push(prime);
      console.log(primeArray);
      numArray.splice(j, 1);
      console.log(numArray);


      for (var k = 0; k < numArray.length; k++) {
        if (numArray[k] % prime == 0) {
          numArray.splice(k, 1);
        };
      }

    }

  };

}


p = 5;
console.log(checkIfPrime(p));

2 个答案:

答案 0 :(得分:2)

Since you are more interested in suggestions than working code, lets start with with alternatives.

Issue is, when you splice an item from array, it changes its length. Nothing new in it, but the issue is, you are iterating over same array.

So for a given array [2, 3, 4, 5], if j is 0, prime will 2. So you remove 2 and 4. So the new length is 2. Issue is the remaining elements will be shifted. So it would look like [3, 5].

Now in the iteration, j will be 1. So it will start from 5 and will skip 5.

Alternative:

Instead of removing elements, assign them to a default value that will be skipped by default. This way, your index will remain correct and your logic will be simple.

function checkIfPrime(p) {
  var numArray = [];
  var primeArray = [];

  for (var i = 2; i < (p + 1); i++) {
    numArray.push(i);
  };

  for (var j = 0; j < numArray.length; j++) {
    if (numArray[j] !== 0 && primeArray.indexOf(numArray[j]) === -1) { //if numArray of j is not already in primeArray
      var prime = numArray[j];

      primeArray.push(prime);

      for (var k = 0; k < numArray.length; k++) {
        if (numArray[k] % prime == 0) {
          numArray[k] = 0;
        };
      }
    }
  };
  console.log(primeArray)
}


p = 5;
console.log(checkIfPrime(p));


splice every multiple of prime from numArray

The simplest way is to use Array.filter. If you manipulate array while looping itself, it will complicate logic. Also, an object should be immutable. So, you can loop over array and create a temp array with necessary values and replace the value.

This can be done using array.filter or even using for.

numArray = numarray.filter(function(num){
  return num % prime !== 0;
})

Assuming numArray will have possible prime numbers, we can try to minimize the obvious non-candidates.

var numArray = [2, 3];

for (var i = 8; i<=p; i++) {
  if(i % 2 !== 0 || i % 3 !== 0) {
    numArray.push(i)
  }
}

Also, since prime numbers are fixed, we can assume a length and pre-compute list of prime numbers. If user enters a bigger number, you just have to compute numbers from limit to new limit. This way you are saving some processing time:

var numArray = [2, 3];

function computePrimes(limit) {
  var init = numArray[numArray.length - 1] || 0;
  for (var i = init; i<= limit; i++) {
    if(isPrime) {
      numArray.push(i);
    }
  }
}

function isPrime(num) {
  for (var i = 3; i< num; i++) {
    if(num % i === 0)
      return true;
  }
  else false;
}

computePrimes(100);

function getPrimeNumbers(num) {
  if(num > numArray[numArray.length - 1]) {
    computePrimes(num);
  }
  // ... Your computation logic
}

答案 1 :(得分:1)

正如迈克所说,在修改数组时使用for循环迭代数组通常是个坏主意。

我认为有两种方法可以解决这个问题:

手动管理迭代变量并确保仅在需要时递增。

或者使用数组的过滤方法。这是帮助您入门的基本示例:

[1,2,3].filter(function(x){return x != 2})
// Will return [1,2]

请注意,这会返回一个包含过滤值的新数组,因此您必须通过执行类似numArray = numArray.filter(...)

的操作来重新定位它