编写一个程序来显示“的所有字谜”;abcdef“;用Python
我的朋友编写了一段代码,用python显示“abcdef”的所有字谜。但是在这段代码中,我无法理解递归过程是如何工作的编写一个程序来显示“的所有字谜”;abcdef“;用Python,python,anagram,Python,Anagram,我的朋友编写了一段代码,用python显示“abcdef”的所有字谜。但是在这段代码中,我无法理解递归过程是如何工作的anagrams=get\u list\u of\u anagrams('''.join(tmp\u list))函数如何调用自身 def get_list_of_anagrams(s): if len(s)==0: return [''] all_chars = list(s) unique_chars = list(set(s))
anagrams=get\u list\u of\u anagrams('''.join(tmp\u list))
函数如何调用自身
def get_list_of_anagrams(s):
if len(s)==0:
return ['']
all_chars = list(s)
unique_chars = list(set(s))
anagrams_list = []
for char in unique_chars:
tmp_list = list(all_chars)
tmp_list.remove(char)
anagrams = get_list_of_anagrams(''.join(tmp_list))
for i in range(len(anagrams)):
anagrams[i] = char+anagrams[i]
anagrams_list += anagrams
return anagrams_list
当我试着打印每件事直到anagrams=get\u list\u of\u anagrams(''.join(tmp\u list)
我把下面的东西拿出来
对于以下代码:
def get_list_of_anagrams(s):
if len(s)==0:
return ['']
all_chars = list(s)
unique_chars = list(set(s))
anagrams_list = []
for char in unique_chars:
tmp_list = list(all_chars)
tmp_list.remove(char)
anagrams = get_list_of_anagrams(''.join(tmp_list))
print anagrams
for i in range(len(anagrams)):
anagrams[i] = char+anagrams[i]
anagrams_list += anagrams
return anagrams_list
print get_list_of_anagrams('abc')
我得到以下输出:
有人能解释一下为什么上面的输出是这种模式吗?这是一个递归函数。
例如著名的斐波那契序列:
def fib(n):
if n < 2:
return n
return fib(n-2) + fib(n-1)
print fib(10)
def fib(n):
如果n<2:
返回n
返回fib(n-2)+fib(n-1)
打印fib(10)
查看更多信息。通过以下方式跟踪:
def get_list_of_anagrams(s):
# base case - empty string, return empty
if len(s)==0:
return ['']
# figure out which characters are available
all_chars = list(s) # may have repeats
unique_chars = list(set(s)) # no repeats
# prepare to store all results
anagrams_list = []
# for each unique character
for char in unique_chars:
# remaining unused characters
tmp_list = list(all_chars)
tmp_list.remove(char)
# recurse: get all anagrams of remaining characters
anagrams = get_list_of_anagrams(''.join(tmp_list))
# prefix each result with picked character
for i in range(len(anagrams)):
anagrams[i] = char+anagrams[i]
# add to overall results
anagrams_list += anagrams
# return all results
return anagrams_list
我会重写一下,就像
def get_list_of_anagrams(s):
anagrams = []
remaining = list(s)
for char in sorted(set(s)):
remaining.remove(char)
if remaining:
# recurse: get all anagrams of remaining characters
for anagram in get_list_of_anagrams(remaining):
# prefix each result with picked character
anagrams.append(char + anagram)
else:
anagrams.append(char)
remaining.append(char)
# return all results
return anagrams
因此,要查找get\u-list\u-of-anagrams(“abcdef”)
,您需要
"a" + each(get_list_of_anagrams("bcdef"))
"b" + each(get_list_of_anagrams("acdef"))
"c" + each(get_list_of_anagrams("abdef"))
"d" + each(get_list_of_anagrams("abcef"))
"e" + each(get_list_of_anagrams("abcdf"))
"f" + each(get_list_of_anagrams("abcde"))
等等。这个想法是,要找到
'abc'
的字谜,首先要找到'bc'
的所有字谜,首先要找到'c'
的所有字谜,首先要找到'
的所有字谜
那么,给定“内层”的所有字谜,你如何找到“外层”的字谜呢?给定'bc'
的所有字谜(它们是'bc'
和'cb'
),您可以通过将a
插入'bc'
和'cb'
的每个位置来查找'abc'
的所有字谜。详细信息:
# 'bc' will give these anagrams:
abc # insert 'a' at first position
bac # insert 'a' at second position
bca # insert 'a' at third position (also last)
# Similarly, 'cb' gives:
acb
cab
cba
因此,2个'bc'
的字谜给你6个'abc'
的字谜
===
关于您的算法:它在每次递归时删除1个字符(使用
tmp_list.remove(char)
)。在len=0的基本情况下(即当所有字符都已删除时),它只返回'
。然后使用上述逻辑继续查找'f'
的字谜,然后查找'ef'
…的字谜,最后返回abcdef的字谜
import itertools
d = 'abc'
e = len(d)
j = list()
for p in itertools.permutations(d, e):
print p
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')
我知道这是一个递归函数。但我不明白它是如何在这种情况下应用的。我试图更改链接,使其成为一个真正的递归定义;-)在你的函数中,你会得到一个空列表,因为与你的朋友编写的return['']
相比,它只return[']
和返回字谜列表
。要理解递归函数,请尝试找到退出(返回并从那里跟踪范围内的i(len(anagrams)):
但len(anagrams)不是空的吗。因为当我打印字谜时,我会得到一个空列表。那么为什么我的朋友在len(anagrams)上循环的代码是空的呢?把这个命令print anagrams
放在anagrams=get\u list\u of anagrams('''.join(tmp\u list))
后面。它将向您展示如何递归works@whale_steward好的,我试试这个one@whale_steward-我试过你的建议。但每次迭代之后,我都会得到一个空列表[“”],然后是一个单词。在这个场景中,递归是如何实现的,我对此感到困惑。除了递归部分,我什么都懂。例如,斐波那契解释了递归()。这个问题中的递归函数也有类似的逻辑吗?您的解决方案非常好:)。是否可以不使用递归编写此函数。我知道这是离题的,但如果您能帮助我,这将是非常棒的。我认为它可以作为一个迭代算法编写-Knuth的置换算法稍加修改,以防止相同的字母重复(即“abcb”只应返回一次)。事实上,Knuth可能包括了这个,你必须检查一下。基本上,它涉及到根据一组规则重复地重新排列字母列表,例如参见itertools.permutations
的源代码。它比递归解决方案快一点(但也很难理解)。好的,我肯定会看一下itertools.permutations。每次迭代后,我都会得到一个空列表[“”],然后是一个单词。在这个场景中,递归是如何实现的,我对此感到困惑。你能给我解释一下吗?嗨,Huy,我已经更新了问题。通过你的解释,我能百分之五十地听懂你的解释。但我不明白为什么我会有这样的模式。
import itertools
d = 'abc'
e = len(d)
j = list()
for p in itertools.permutations(d, e):
print p
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')