Почему эта рекурсивная функция превышает размер стека вызовов? - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь написать функцию, чтобы найти наименьшее число, которое делят все целые числа от 1 до 20.(Давайте назовем это Условие D)

Вот мое решение, которое как-то превышает предел размера стека вызовов.

function findSmallest(num){
    var count = 2
    while (count<21){
        count++
        if (num % count !== 0){
            // exit the loop
            return findSmallest(num++)
        }

    }
    return num
}

console.log(findSmallest(20))

Где-то мои рассуждения об этом ошибочны, но вот как я это вижу (пожалуйста, поправьте меня, где я ошибаюсь):

Вызов этой функции с номером N, который не соответствует условию D, приведет к повторному вызову функции с N + 1. В конце концов, когда она достигнет номераM, которое должно удовлетворять условию D, цикл while проходит весь путь, и функция возвращает число M, и больше нет рекурсивных вызовов.

Но я получаю эту ошибку при запуске:

function findSmallest (num) {^

RangeError: Превышен максимальный размер стека вызовов

Я знаю, что подобные ошибки почти всегда происходят из-за того, что рекурсивные функции не достигают базового случая.Это проблема здесь, и если да, то где проблема?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Ваша проблема в том, что вы вводите рекурсию более 200 миллионов раз (плюс ошибка, обнаруженная в предыдущем ответе).Число, которое вы ищете, умножается на все простые числа, умноженные на их максимальные вхождения в каждом числе определенного диапазона.Итак, вот ваше решение:

function findSmallestDivisible(n) {
    if(n < 2 || n > 100) {
    throw "Numbers between 2 and 100 please";
  }
    var arr = new Array(n), res = 2;
  arr[0] = 1;
  arr[1] = 2;
  for(var i = 2; i < arr.length; i++) {
    arr[i] = fix(i, arr);
    res *= arr[i];
  }
  return res;
}

function fix(idx, arr) {
    var res = idx + 1;
  for(var i = 1; i < idx; i++) {
    if((res % arr[i]) == 0) {
        res /= arr[i];
    }
  }
  return res;
}

https://jsfiddle.net/7ewkeamL/

0 голосов
/ 18 мая 2018

Я обнаружил две ошибки.

  • в вашем цикле while, значение count составляет от 3 до 21.
  • значение num изменяется в цикле.num++ должно быть num + 1

Однако, даже если эти ошибки исправлены, ошибка не будет устранена.Ответ 232792560.Эта глубина рекурсии слишком велика, поэтому стековая память исчерпана.

Например, этот код вызывает ту же ошибку.

function foo (num) {
    if (num === 0) return
    else foo(num - 1)
}

foo(232792560)

При кодировании без рекурсии можно избежать ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...