解释用于回溯算法的Python示例代码

时间:2018-08-04 00:34:49

标签: python algorithm backtracking recursive-backtracking

在PacktPub的书“ Python数据结构和算法”(由Benjamin Baka撰写)的第3章中的回溯部分中,它们具有此功能(第81页):

def bitStr(n, s):
    if n == 1: return s
     return [digit + bits for digit in bitStr(1, s) 
             for bits in bitStr(n - 1, s)]

 print(bitStr(3,'abc'))

返回:

['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']

这本书的解释:

  

注意双重列表压缩和内部的两个递归调用   这种理解。这递归地连接了   初始序列,在n = 1时返回,带有字符串的每个元素   在上一个递归调用中生成。从这个意义上讲   回溯以发现先前生成的组合。决赛   返回的字符串是首字母的所有n个字母组合   字符串。

好吧,除了他们对这样的事情(或者也许只是我)使用列表理解的感觉是多么的不可思议之外,我简直无法理解。

我重写了整个内容,并将注释添加到代码中,包括到目前为止所了解的内容以及卡住的位置。

def test(n, s):
     # this one's obvious
     if n == 1: return s

     result = list() # so's this

     """
     From what I can tell, the first recursive call in the outer
     loop forces the function's conditional statement to 
     activate. So, with the example of `abc` as the second
     input to the function, the outer for loop just loops
     over that string, `abc` in this case.
     """
     for digit in test(1, s):
         """
         This is where I start to lose my grip on what's happening.
         So, going to the above returned list as given by the book,
         I can see where the first item, i.e `aaa`, in the list
         comes from.

         So, here's what I see when it comes to that first item. 
         `digit` now storing the first 'a' that later get's added,
         the second recursive call in this second loop (if w-
         e're going with the original example call from the 
         book: `test(3, 'abc')`) sets the first input to 2 on
         the first iteration.

         I'm guessing this makes it so it avoids the conditional 
         statement. With that avoided, we still have the string
         'abc'. 

         The first iteration of the loop takes the first 
         letter, 'a', and adds it to `digit`. 

         I'm a bit confused on how then the loop goes back through 
         the function to get the third 'a' to complete the 
         final list's first item, 'aaa'.

         Though, say I did understand that at the time of posting
         this question, what I'm totally confused about it is
         how this supposedly 'Backtracks', and gets the
         final list's second item, 'aab', and all subsequent items.
         """
         for bits in test(n-1, s):
             result.append(digit + bits)

     return result

任何帮助解释这一切的人将不胜感激。另外,如果有人可以确认正确的“我声明”以理解我的代码注释中的内容,那就太好了。

0 个答案:

没有答案