我在activestate找到了这个代码,它需要一个字符串并打印字符串的排列。 我知道它是一个递归函数,但我真的不明白它是如何工作的,如果有人可以引导我完成程序流程,那就太好了,谢谢你们!
import sys
def printList(alist, blist=[]):
if not len(alist): print ''.join(blist)
for i in range(len(alist)):
blist.append(alist.pop(i))
printList(alist, blist)
alist.insert(i, blist.pop())
if __name__ == '__main__':
k = 'love'
if len(sys.argv) > 1: k = sys.argv[1]
printList(list(k))
答案 0 :(得分:6)
您可以通过绘制递归树来了解printList
的行为方式。每个节点由两个元素组成:alist
和blist
。根目录包含alist
,其中包含您要置换的项目的初始序列,以及空blist
。
树的每个节点对该节点的alist
的每个元素都有一个分支;通过从父亲的alist
中选择一个元素,你从'父'节点移动到每个'子节点'并且:
alist
父亲的alist
减去该元素; blist
分配父亲的blist
以及附加在其末尾的 叶子有一个空的alist
,并且由于遵循从根到叶子的不同路径,你必须以不同的顺序从根alist
中选择元素,blist
叶子本身包含根alist
的所有各种排列。
例如([abc],[] == alist,blist
):
[abc],[]
/ | \
a/ b| \c
/ | \
[bc],[a] [ac],[b] [ab],[c]
/ \
b/ \c
/ \
[c],[ab] [b],[ac]
| |
c| |b
| |
[],[abc] [],[acb]
def printList(alist, blist=[]):
# if alist is empty, we are in a 'leaf' in the recursion tree;
# then blist contains one permutation; print it
if not len(alist): print ''.join(blist)
# ELSE, for each possible position in alist,
for i in range(len(alist)):
# move the element at that position from alist to the end of blist
blist.append(alist.pop(i))
# go to the 'children' node and do the printing job for its subtree
printList(alist, blist)
# then move back the element from the end of blist to its original
# position in alist, so we can continue with the for loop
# without altering alist
alist.insert(i, blist.pop())
答案 1 :(得分:3)
要理解它清楚地删除循环,使用alist = love和blist初始化为[]: for循环中的4个printlist调用现在将是(在递归的第一级):
printList("ove","l");
printList("lve","o");
printList("loe","v");
printList("lov","e");
这些printList调用中的每一个都将bList初始化为一个字母列表的所有可能排列,并且alist具有剩余的3个字母。这将继续,直到alist变空并且所有字母都是blist(并且打印发生if not len(alist): print ''.join(blist)
)
在第二级递归中,例如
printList("ove","l") will result in 3 calls
printList("ve","lo");
printList("oe","lv");
printList("ov","le");
总排列= 4(第一级)* 3(第二级)* 2 * 1
答案 2 :(得分:0)
无耻插件 - 这是python中的基本排列代码以及我博客的解释。 Playing with recursion - string permutation