我想生成给定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。但是,这也使我感到效率低下。
有什么建议吗?
答案 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']