2017-07-06 90 views
0
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')) 

該函數打印序列的排列列表,但我不確定inner for循環是如何工作的。我曾嘗試使用trace()來查看控制是如何通過循環移動的,但我無法確定循環第二次如何工作。第一次,' rest '的值是'bc','c'內循環在每次迭代時如何附加?

+0

在一張紙上寫下變量,然後假裝你是執行每個語句的計算機。 – Barmar

+0

你使用什麼樣的IDE?嘗試利用斷點和打印語句。對於調試和理解迭代非常有用 –

+0

僅供參考,'seq [:i] + seq [i + 1:]'只是seq [i]'被刪除的字符串,'seq [i:i + 1]與'seq [i]'相同。 – Barmar

回答

0

每次通過for i循環時,rest將被設置爲輸入字符串,並刪除一個字符。第一次刪除第一個字符,第二次刪除第二個字符等。seq[:i]i之前的每個字符,而seq[i+1:]i之後的每個字符。

然後它在rest上遞歸地調用它自己。這將返回該較短字符串的所有排列。所以當rest"bc"時,這返回["bc", "cb"]for x循環遍歷此列表,並將每個連接到seq[i:i+1](這是創建rest時刪除的字符),並將其附加到res

所以主循環的第一次迭代設置rest"bc",然後追加​​和"acb"res

第二次迭代做同樣的事,與rest設置爲"ac",並seq[i:i+1]作爲缺少的字符"b",所以追加"bac""bca"res

的第三次迭代是相似的,與rest設置爲"ab",所以它追加"cab""cba"res

特殊情況是遞歸的基本情況。如果輸入字符串爲空,我們只返回一個帶有空字符串的列表 - 一個空字符串具有微不足道的排列。當呼叫者執行其for x循環時,它將簡單地將該空字符串連接到當前字母。這種情況是需要防止無限遞歸的。由於單個字母的排列也是微不足道的,因此您也可以使用基本情況。

相關問題