Как элегантно и обязательно сгенерировать n-ую строку алфавита? - PullRequest
0 голосов
/ 26 апреля 2018

Учитывая алфавит, такой как: ["a","b","c","d"], последовательность всех строк, составленных из символов этого алфавита:

""
"a"
"b"
"c"
"d"
"aa"
"ab"
"ac"
...

Haskell может сгенерировать n-й элемент этой последовательности элегантно и рекурсивно:

nth :: Int -> String
nth n = reverse $ alphabet !! n where
    alphabet = [""] ++ concatMap (\ str -> map (: str) "abcd") alphabet

Но это неэффективно. Используя базовые преобразования, вы можете попытаться сгенерировать их обязательно как (используя JavaScript только для демонстрации):

function nth(n) {
  var str = "";
  while (n > 0) {
    str += String.fromCharCode(97 + n % 4);
    n = Math.floor(n / 4);
  }
  return str;
};

for (var i = 0; i < 64; ++i) {
  console.log(nth(i));
}

Но на самом деле это создает следующую последовательность:

""
"b"
"c"
"d"
"ab"
"bb"
"cb"
"db"
"ac"
"bc"
"cc"
"dc"
"ad"
"bd"
"cd"
"dd"
"aab"

Что не является желаемым: обратите внимание на пропущенные «a», «aa», «ba» и т. Д. Я, вероятно, пропускаю какую-то простую операцию, чтобы исправить императивную реализацию, поэтому мой вопрос: есть ли элегантный способ императивно сгенерировать n-ю строку алфавита?

1 Ответ

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

Вставьте n-- в начале цикла while. Если вы хотите получить результаты в коротком лексикографическом порядке, перед печатью измените строку.

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