如何优雅地和命令性地生成字母表的第n个字符串?

时间:2018-04-26 18:01:40

标签: algorithm language-agnostic

给定一个字母如:["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 :(得分:2)

在while循环的开头插入n--。如果希望结果采用较短的字典顺序,请在打印前反转字符串。