Почему моя функция не работает, когда я использую соединение?

Я пытаюсь написать функцию, которая должна вычислять все простые числа до входного параметра и возвращать его. Я делаю это для практики.

Я написал эту функцию несколькими способами, но я пытался найти новые способы сделать это для большей практики и лучшей производительности. Последнее, что я попробовал, был код ниже:

function primes(num){
  let s = []; // sieve
  for(let i = 2; i <= num; i++){
    s.push(i);
  }
  for(let i = 0; i < s.length; i++) {

    for(let j = s[i]*s[i]; j <= num;) {
      //console.log(j);
      if(s.indexOf(j)!= -1){

        s.splice(s.indexOf(j), 1, 0);

      }
      j+=s[i];
    }
  }
  s = s.filter(a => a != 0);
  return s;
}
console.log(primes(10));

Проблема в том, что когда я запускаю это в браузере, он продолжает вычислять и не останавливается, и я не знаю почему.

Примечание: когда я закомментирую splice и раскомментируйте console.log(j); все работает, как ожидалось, и журналы это то, что они должны быть, но с splice, браузер продолжает рассчитывать и не остановится.

Я использую последнюю версию Chrome, но не думаю, что это может иметь какое-либо отношение к проблеме.

2 ответа

Ваша проблема заключается в этой строке:

s.splice(s.indexOf(j), 1, 0);

Splice Третий аргумент функции содержит элементы, которые будут добавлены вместо удаленных элементов. Это означает, что вместо удаления элементов вы меняете их значения на 0, что затем останавливает ваш j-цикл. Чтобы это исправить, просто опустите третий параметр.

function primes(num){
  let s = []; // sieve
  for(let i = 2; i <= num; i++){
    s.push(i);
  }
  for(let i = 0; i < s.length; i++) {

    for(let j = s[i]*s[i]; j <= num;) {
      //console.log(j);
      if(s.indexOf(j)!= -1){

        s.splice(s.indexOf(j), 1);

      }
      j+=s[i];
    }
  }
  return s;
}
console.log(primes(10));

Ваша проблема в этом цикле:

for(let j = s[i]*s[i]; j <= num;)

Это цикл зацикливается навсегда, потому что j всегда меньше или равно num в любом случае вы тестируете. Очень трудно точно определить, когда этот код начнет бесконечный цикл, потому что вы изменяете список по мере цикла.

В действительности же, splice Команда будет называться установка некоторой части индексов в s до 0, что означает, что j+=s[i] больше не выведет вас из цикла.

Другие вопросы по тегам