Рекурсивная функция - Расчет квадратного корня - Слишком много рекурсии - PullRequest
2 голосов
/ 27 мая 2019

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

В настоящее время рекурсивная функция с оператором if .. else используется для выполнения вычислений и корректирует предположение, пока оно не достигнет заданного пользователем целевого числа при возведении в квадрат.

Функция обеспечивает правильный ответ для 11, 22, 33, 44, 55, любого числа, где квадратный корень не является десятичным, среди прочих. Однако он возвращает ошибку - слишком много рекурсии с другими числами, такими как 13, хотя программа очень близко подходит к решению проблемы - обычно всего на .00000000000000x выше или ниже целевого числа.

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

Предыдущие итерации достигли ошибки слишком большого количества рекурсий намного раньше и возвращали правильные результаты только для чисел, в которых правильный ответ был получен в течение первого прогона функции, иначе мой браузер завис бы.

// HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Function library example</title>
  <style>
    input {
      font-size: 2em;
      margin: 10px 1px 0;
    }
  </style>
</head>
<body>

  <input class="numberInput" type="text">
  <p></p>

// JavaScript

  <script>
      var input = document.querySelector('.numberInput');
      var para = document.querySelector('p');

  function findSquareRoot(num){
    function find(guess, square, lastSmallGuess, lastLargeGuess){
      var smallerArray = [];
      var greaterArray = [];

      if(square == num){
        return guess;
      } else if(square > num){
          greaterArray.push(guess);
          console.log('Last Small Guess : ' + lastSmallGuess); // shows guess in developer tools
          console.log(' Last Large Guess : ' + lastLargeGuess); // shows guess in developer tools
          console.log((((guess * 1) + (lastSmallGuess * 1)) / 2), (((guess * 1) + (lastSmallGuess * 1)) / 2) * (((guess * 1) + (lastSmallGuess * 1)) / 2), lastSmallGuess, greaterArray[greaterArray.length-1]); // shows calculation process in dev tools
          return find((((guess * 1) + (lastSmallGuess * 1)) / 2), (((guess * 1) + (lastSmallGuess * 1)) / 2) * (((guess * 1) + (lastSmallGuess * 1)) / 2), lastSmallGuess, greaterArray[greaterArray.length-1]);
      } else if(square < num){
          smallerArray.push(guess);
          console.log('Last Small Guess : ' + lastSmallGuess);  // shows guess in developer tools
          console.log(' Last Large Guess : ' + lastLargeGuess); // shows guess in developer tools
          console.log((((guess * 1) + (lastLargeGuess * 1)) / 2), (((guess * 1) + (lastLargeGuess * 1)) / 2) * (((guess * 1) + (lastLargeGuess * 1)) / 2), smallerArray[smallerArray.length-1], lastLargeGuess); // shows calculation process in dev tools
          return find((((guess * 1) + (lastLargeGuess * 1)) / 2), (((guess * 1) + (lastLargeGuess * 1)) / 2) * (((guess * 1) + (lastLargeGuess * 1)) / 2), smallerArray[smallerArray.length-1], lastLargeGuess);
    } 
  }
  return find((num * 1) / 2, ((num * 1) / 2) * ((num * 1) / 2), 0, 0);
}

  input.onchange = function() {
    var num = input.value;
    if(isNaN(num)) {
      para.textContent = 'You need to enter a number!';
    } else {
      para.textContent = num + ' square root is ' + findSquareRoot(num) + '. ' +
                       num + ' square root is ' + Math.sqrt(num) + '.';
    }
  }
  </script>
</body>
</html>

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

Спасибо, что нашли время, чтобы прочитать мой вопрос.

...