def per1(seq):
if not seq:
return [seq]
else:
res=[]
for i in range(len(seq)):
rest=seq[:i]+seq[i+1:]
for x in per1(rest):
res.append(seq[i:i+1]+x)
return res
print(per1('abc'))
该函数是打印一个置换的序列列表,但我不确定内部for循环是如何工作的。我曾尝试使用trace()
来查看控件是如何通过循环移动的,但我无法确定循环第二次如何工作。第一次,' rest '
值为'bc','c'
。
答案 0 :(得分:0)
每次通过for i
循环时,rest
都会设置为输入字符串,并删除一个字符。第一次删除第一个字符时,第二次删除第二个字符,等等seq[:i]
是i
之前的每个字符,而seq[i+1:]
是{{1}之后的每个字符}}
然后它在i
上递归调用自己。这将返回该较短字符串的所有排列。因此,当rest
为rest
时,会返回"bc"
。 ["bc", "cb"]
循环遍历此列表,并将每个链接连接到for x
(创建seq[i:i+1]
时删除的字符),并将其附加到rest
。< / p>
因此,主循环的第一次迭代将res
设置为rest
,然后将"bc"
和"abc"
追加到"acb"
。
第二次迭代做同样的事情,res
设置为rest
,"ac"
是缺失字符seq[i:i+1]
,因此它附加"b"
和"bac"
至"bca"
。
第三次迭代类似,res
设置为rest
,因此它将"ab"
和"cab"
追加到"cba"
。
特殊情况是递归的基本情况。如果输入字符串为空,我们只返回一个带有该空字符串的列表 - 空字符串具有简单的排列。当调用者执行其res
循环时,它将简单地将此空字符串连接到当前字母上。需要这种情况来防止无限递归。您也可以将for x
作为基本情况,因为单个字母的排列也很简单。