在Python中生成字符串的所有排列而不使用itertools

时间:2015-10-23 22:49:46

标签: python permutation

我需要生成字符串中所有字符的可能排列(重复)。如果字符串是'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,例如!

有更好的方法吗?

2 个答案:

答案 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']