2012-08-16 84 views
4

今天我在思考这个问题的所有字谜,我想出了下面的伪代码(Python的3.2):生产从字符串蟒蛇

def anagrams(string): 

    for c in string: 
     anagram = c + anagram(string - {c}) # remove the char from its position in the string 
     print(anagram) 

    return 

def main(): 

    word = "abcd" 
    anagrams(word) 

    return 

不过,我想知道一个Python化的方式来做这个操作: anagram = c + anagram(string - {c})

如何从字符串中删除该字符?因此,例如:

"abc" -> 'a' + "bc" -> 'a' + 'b' + "c" -> 'a' + 'b' + 'c' = 'abc' 
      + "cb" -> 'a' + 'c' + "b" -> 'a' + 'c' + 'b' = 'acb' 
     -> 'b' + "ac" -> 'b' + 'a' + "c" -> 'b' + 'a' + 'c' = 'bac' 
      + "ca" -> 'b' + 'c' + "a" -> 'b' + 'c' + 'a' = 'bca' 
     -> 'c' + "ba" -> 'c' + 'b' + "a" -> 'c' + 'b' + 'a' = 'cba' 
      + "ab" -> 'c' + 'a' + "b" -> 'c' + 'a' + 'b' = 'cab' 

感谢

回答

16

为什么不只是使用itertools

>>> import itertools 
>>> ["".join(perm) for perm in itertools.permutations("abc")] 
['abc', 'acb', 'bac', 'bca', 'cab', 'cba'] 

documentation还包含代码如何完成排列。


编辑:

Without itertools

def all_perms(elements): 
    if len(elements) <=1: 
     yield elements 
    else: 
     for perm in all_perms(elements[1:]): 
      for i in range(len(elements)): 
       yield perm[:i] + elements[0:1] + perm[i:] 


word = "abc" 
print list(all_perms(word)) 

没有itertools,没有generators

def all_perms(elements): 
    if len(elements) <=1: 
     return elements 
    else: 
     tmp = [] 
     for perm in all_perms(elements[1:]): 
      for i in range(len(elements)): 
       tmp.append(perm[:i] + elements[0:1] + perm[i:]) 
     return tmp 

结果:

[ 'ABC', 'BAC', 'BCA', 'ACB', '出租车', 'CBA']

+0

为什么使用下划线作为变量名称,而不是像'permutation'或其他什么东西一些描述性的东西......? (否则,很好的答案) – mgilson 2012-08-16 14:41:23

+0

BigYelloCactus,我喜欢你的答案,但我需要一个递归方法,如图所示,可以使用任何编程语言(又名:C) – cybertextron 2012-08-16 14:42:59

+0

变量的名称* always *很重要。它可以让用户知道变量*代表的是什么。使用'_'表示“我不打算使用这个函数的输出”,但是你会*使用输出。 – mgilson 2012-08-16 14:43:58

3

使用itertools模块。

import itertools 
perms = [''.join(perm) for perm in itertools.permutations('abc')] 
+1

是'名单( ''.join等)或'[''.join等]'可以自行工作;没有必要做这两件事。 – DSM 2012-08-16 14:41:34

+0

谢谢,我没有听清楚。 – Lanaru 2012-08-16 14:45:07

+0

我需要一个递归方法,如图所示,任何编程语言都可以使用(又名:C),但为你的工作做好+1! – cybertextron 2012-08-16 14:48:11

0

,就可以把单词的列表,运行捞出然后使用连接重新将它重新组合在一起。

word = 'abca' 
letters = list(word) 
letters.remove('a') # Only deletes the first 'a' 
word = ''.join(letters) 
1

只是要注意,@懒惰的回答给出了一个略显意外的结果,如果字符串包含一个字母的多个实例 - 重复排列:

['aabc', 
'aacb', 
'abac', 
'abca', 
'acab', 
'acba', 
'aabc', 
'aacb', 
'abac', 
'abca', 
'acab', 
'acba', 
'baac', 
'baca', 
'baac', 
'baca', 
'bcaa', 
'bcaa', 
'caab', 
'caba', 
'caab', 
'caba', 
'cbaa', 
'cbaa'] 
:在

["".join(perm) for perm in itertools.permutations('aabc')] 

结果

如果这不是理想的结果,使用'set'将消除dups。但如果你想有一个列表,你需要重新登录(也“设定”不维持秩序,所以用“排序”):

sorted(set(["".join(perm) for perm in itertools.permutations("aabc")])) 

结果:

['aabc', 
'aacb', 
'abac', 
'abca', 
'acab', 
'acba', 
'baac', 
'baca', 
'bcaa', 
'caab', 
'caba', 
'cbaa']