生成所有长度为l的n个字符的字符串

时间:2018-12-10 07:26:20

标签: string algorithm permutation

我想生成给定n个字符的,一定长度l的所有可能字符串。

例如,如果l = 2并且字符为[a,b,c],则结果应为: 'aa','ab','ac','ba','bb','bc','ca','cb'和'cc'。

最初,我是使用递归算法来完成此操作的。但是,我得到了很多重复副本,这非常耗时。

此外,我想到了一种以n为底数的算法。因此,在上面的示例中,如果我替换a-> 0,b-> 1和c-> 2,我实际上将基数3计为'cc'->22。但是,这也使我感到效率低下。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

您不必实施任何建议。您要做的就是从上一个项目中获取下一个项目

 aa -> ab -> ac -> : we can't add 1 to c so why reset the last 'c' to 'a' 
                     but add 1 to previous 'a': 'ba'
                     now we keep on adding one to the last 'a':
 ba -> bb -> bc -> : again we reset 'c' to 'a' and increment previous b
 ca -> ...

代码(C#);让我们概括解决方案(不需要的任何alphabet string

// alphabet should contain distinct items
private static IEnumerable<T[]> Solution<T>(IEnumerable<T> alphabet, int length) {
  if (null == alphabet)
    throw new ArgumentNullException(nameof(alphabet));

  var chars = alphabet.Distinct().ToArray();

  if (length <= 0 || chars.Length <= 0)
    yield break;

  int[] result = new int[length];

  do {
    yield return result
      .Select(i => chars[i])
      .ToArray();

    for (int i = result.Length - 1; i >=0 ; --i)
      if (result[i] == chars.Length - 1) 
        result[i] = 0;
      else {
        result[i] += 1;
        break;
      }
  }
  while (!result.All(item => item == 0));
}

演示:

// Or     var test = Solution("abc", 2);
var test = Solution(new char[] { 'a', 'b', 'c' }, 2);

var report = string.Join(", ", test
  .Select(item => string.Concat(item)));

结果:

aa, ab, ac, ba, bb, bc, ca, cb, cc

答案 1 :(得分:0)

是的,您可以使用除法表示“计数基数n”。

另一种实现方式-使用类似旧电动计数轮的方法遍历所有n^m值:

src = "abc";
n = len(src)
m = 2
l = [0]*m
i = 0
while i < m:
    print([src[x] for x in l])
    i = 0
    l[i] += 1
    while (i < m) and l[i] >= n:
        l[i] = 0
        i += 1
        if i < m:
            l[i] += 1

['a', 'a']
['b', 'a']
['c', 'a']
['a', 'b']
['b', 'b']
['c', 'b']
['a', 'c']
['b', 'c']
['c', 'c']