рекурсивная строка javscript - PullRequest
0 голосов
/ 25 апреля 2020

Я попытался самостоятельно найти рекурсивное решение для обращения строки s, но она возвращает 'undefined' для строк> 1 символа. Может кто-нибудь помочь мне отладить это? Я знаю, что это не элегантный способ, но обнаружение ошибки может помочь мне продвинуться вперед.

Спасибо большое!

var revFunc = function (s, r, n, i) {
  if (i > n) {
    return r;
  }

  r = r + s[n - i];
  i++;
  revFunc(s, r, n, i);
};

var reverse = function (s) {
  var r = "";
  var n = s.length - 1;
  var i = 0;
  if (n < 1) {
    return s;
  }
  return revFunc(s, r, n, i);
};

Ответы [ 3 ]

0 голосов
/ 25 апреля 2020

Вы забыли return

return revFunc(s, r, n, i);

Обновлено:

var revFunc = function (s, r, n, i) {
  if (i > n) {
    return r;
  }
  r = r + s[n - i];
  i++;
  return revFunc(s, r, n, i);
};

Предложение: Пожалуйста, используйте лучшее имя для переменных, это отстой s,r,n,i

0 голосов
/ 26 апреля 2020

Не подходит для рекурсии.

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

Ваша функция использует рекурсию для обновить то, что в противном случае было бы локальными переменными через некоторое время l oop. Это можно переписать так:

var reverse = function (s) {
  var r = "";
  var n = s.length - 1;
  var i = 0;
  if (n < 1) {
    return s;
  }
  while (i <= n) {
    r = r + s[n - i]
    i++
  }
  return r
};

console .log (reverse ('abcde'))

Используемая вами рекурсия - это просто еще один способ написания того же кода.

Рекурсия предназначена для чего-то немного другого. Мы хотим, чтобы наши алгоритмы соответствовали нашим структурам данных. Чтобы рекурсия действительно имела смысл, мы должны использовать ее в рекурсивной структуре данных.

Но мы можем сделать это для этой проблемы.

Рекурсивно думать о строке

Часто существует много разных способов представить единую структуру данных. Мы можем представить строку как рекурсивную структуру следующим образом:

Строка может быть либо

  • Пустая строка "", либо
  • a символ, за которым следует строка

Мы можем назвать две части непустой строки head и tail.

Используя рекурсивное определение в рекурсивный алгоритм

С этой формулировкой мы можем написать рекурсивный алгоритм, который соответствует структуре:

Обращение строки либо

  • обращение пустой строки (которая до сих пор является пустой строкой) или
  • обращение хвоста, за которым следует голова

Затем код практически записывается сам:

const reverse = (string) =>
  string .length == 0
    ? ""
    : reverse (string .slice (1)) + string[0]
    
console .log (reverse ('abcdefg'))

Варианты

Конечно, возможны варианты этого. Мы могли бы быть готовы к тому, что оптимизация хвостового вызова, наконец, распространена в JS средах, и могла бы изменить ее на хвостовую рекурсивную версию, что-то вроде

const reverse = (string, result = "") =>
  string .length == 0
    ? result
    : reverse (string .slice (1), string [0] + result)

(обратите внимание, что существует потенциальная проблема с этим стилем. Параметры по умолчанию могут мешать использованию функции в определенных контекстах. Вы не можете, например, успешно вызвать strings .map (reverse) с этой версией. Вы можете сделать это, разделив ее на вспомогательную функцию и основную функция, но это уводит нас в сторону.)

Или, воспользовавшись тем, что строки являются итеративными, мы могли бы написать довольно простую версию, используя деструктуризацию параметров вместе со значением по умолчанию:

const reverse = ([head = undefined, ...tail]) =>
  head == undefined
    ? ""
    : reverse (tail) + head

Преимущества рекурсии

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

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

0 голосов
/ 25 апреля 2020

Можете ли вы попробовать простое решение:

let str = "hello";
let reverse_str = str.split("").reverse().join("");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...