JavaScript: напишите функцию, которая принимает входной символ и возвращает этот символ, повторенный 5 раз с использованием рекурсии - PullRequest
1 голос
/ 14 июня 2019

Напишите функцию, которая принимает входной символ и возвращает этот символ, повторенный 5 раз с использованием рекурсии. Например, если на входе указано «g», то на выходе должно быть «ggggg».

Я попробовал код ниже:

function repeater(char) {

  let newStr = ''; 

  if (newStr.length === 5){
    return newStr; 
  }

  else {
    newStr += char; 
  }

  return repeater(char); 
}

// To check if you've completed the challenge, uncomment these console.logs!
console.log(repeater('g')); // should return 'ggggg'
//console.log(repeater('j')); 'jjjjj'

Мой код возвращает: RangeError: Maximum call stack size exceeded

Что я делаю не так?

Ответы [ 3 ]

2 голосов
/ 14 июня 2019

Причина newStr - локальная переменная, которая не передается в рекурсивном вызове.Поэтому новый newStr будет создаваться при каждом вызове, и его длина всегда будет равна 0. Чтобы решить эту проблему, либо передайте строку, либо длину:

  function repeat(char, result = "") { 
    if(result.length / char.length >= 3) return result;
    return repeat(char, result + char); // ²
 }

 // a call goes like:
 // repeat("g", "")
 // repeat("g", "g")
 // repeat("g", "gg")
 // repeat("g", "ggg")

 // OR

 function repeat(char, count = 3) { /*¹*/
    if(count <= 1) return char;
    return char + repeat(char, count - 1);
 }

 // repeat("g", 3)
 // "g" + repeat("g", 2)
 // "g" + "g" + repeat("g", 1)
 // "g" + "g" + "g"

Или, если это должно толькоработать с одним заданным символом (как говорится в задании):

 function repeat(char) {
   if(char.length >= 3) return char;
   return repeat(char + char[0]); // ²
 }

Примечание. Приведенные выше функции не возвращают 5 повторений.Это оставлено вам в качестве упражнения:)

Если мы откажемся от задания, вы можете просто выполнить "g".repeat(5), хотя ...


¹: = 3 - это такназывается «аргумент по умолчанию».Это означает, что repeat("g") равно repeat("g", 3).Преимущество состоит в том, что вы можете повторно использовать это для различной длины, repeat("g", 10) будет повторяться g 10 раз.

²: Это хвостовой вызов.Если вы поместите рекурсивный вызов в последнюю строку и вернете его, механизм может оптимизировать рекурсию в цикл, который намного быстрее и не достигает максимального размера стека вызовов (бесконечная рекурсия все еще плоха,старайтесь всегда избегать попадания в него. Например, newStr.length === 5 опасно, поскольку строка длиной 6 будет работать вечно. Поэтому я бы рекомендовал использовать >= или <= (как я делал выше)).

1 голос
/ 15 июня 2019

Можно принять значение по умолчанию 5 и вызывать рекурсию до тех пор, пока больше не будет доступных вызовов.

function repeater(char, count = 5) {
    if (!count) return '';                   // exit condition
    return char + repeater(char, count - 1); // repeating part
}

console.log(repeater('x'));
0 голосов
/ 14 июня 2019

Одна вещь в вашем коде заключается в том, что вы вызываете ретранслятор вне условия else, что означает, что он будет вызываться бесконечно. Во-вторых, вы объявляете newStr внутри функции. Вы можете сделать что-то вроде этого.

function repeater(char, oldStr) {
    let newStr = oldStr || '';
    if (newStr.length === 5) {
        return newStr;
    } else {
        newStr += char;
        return repeater(char, newStr);
    }
 }
...