我需要生成字符串中所有字符的可能排列(重复)。如果字符串是'abc',则输出应为:
AAA AAB AAC ABC ... CBC CCA 建行 CCC
我不能使用itertools模块,我不想使用递归(因为这只是一个例子。我真正需要的是输出数百万的排列,我害怕内存耗尽)
我可以这样做:
s = 'abc'
for c1 in range(0, 3):
for c2 in range(0, 3):
for c3 in range(0, 3):
print(s[c1]+s[c2]+s[c3])
基本上,我有多少个循环,因为字符串有字符。 现在假设字符串的长度为10,例如!
有更好的方法吗?
答案 0 :(得分:7)
解决此问题的一个简单方法是将字符串中的字符视为异常数字系统中的数字。字符串的长度是基数。因此static void Main(string[] args)
{
const int min = 2;
const int max = 20;
var accum = min;
for (var i = min; i <= max; i++)
{
accum = lcm(accum, i);
}
Console.WriteLine(accum);
Console.ReadLine();
}
private static int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
private static int lcm(int a, int b)
{
return a/gcd(a, b)*b;
}
的排列(重复)对应于基数3中'abc'
到0
的数字,其中3**3-1
是数字'a'
,{{ 1}}是0
,'b'
是1
。
'c'
示例运行:
2
如果您被允许使用def permutations_with_repetition(s):
base = len(s)
for n in range(base**base):
yield "".join(s[n // base**(base-d-1) % base] for d in range(base))
,则您希望>>> for p in permutations_with_repetition("abc"):
print(p)
aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc
使用itertools
关键字参数:itertools.product
答案 1 :(得分:2)
如果您害怕耗尽内存使用生成器。继续为你的值调用d.next()。它只对小型嵌套循环有效。
>>> s = 'abc'
>>> d =( (x,y,z) for x in s for y in s for z in s)
>>> d.next()
'aaa'
>>> d.next()
'aab'
如果你想要所有值,那么
list(d)
对于任意长度使用:这使得组中的元素与字符串中的元素一样多,然后遍历所有组并继续添加到最终结果。这就是在python中实现itertools.product的方法。有关详细信息,请访问here
def product(x):
final = [[]]
l = len(x)
groups = [list(x)] * l
for i in groups:
final = [x+[y] for x in final for y in i]
for k in final:
yield ''.join(k)
强制所有结果:
list(product('abc'))
['aaa',
'aab',
'aac',
'aba',
'abb',
'abc',
'aca',
'acb',
'acc',
'baa',
'bab',
'bac',
'bba',
'bbb',
'bbc',
'bca',
'bcb',
'bcc',
'caa',
'cab',
'cac',
'cba',
'cbb',
'cbc',
'cca',
'ccb',
'ccc']