How does this recursive functions work to produce all permutations?

时间:2019-04-16 22:38:47

标签: python recursion

I really struggle to understand recursive code. I have copied a block of code I am trying to understand. I have seen this described in a pictorial manner but I don't understand how the program gets to the result.

This is my understanding so far

Initially

  • (ABC, 0, 3) is passed into the function
  • If condition not met SO enter the ELSE branch
  • j is 0 and i is 0 this time (swap first character with first character)
  • **THEN* send new 'data' back into the function and re-reun Question
  • Why does "j" remain increment with i? The for loop hasn't been run to completetion Anyway.... for some reason j and i both increase until i = 3 then print "ABC"
  • So far we haven't gotten beyond the line permute(data, i+1, length)
  • I don't understand why the program then jumps to the permute(data...) line after printing the line "ABC", we are in the "IF" not "ELSE" arm of the "if-else" clause.
  • I then don't understand how we iterate between all characters using "i" and "j".

Does this make sense? Please can someone explain how this code yields all solutions. Thanks

def permute(data, i, length): 
    if i==length: 
        print(''.join(data) )
    else: 
        for j in range(i,length): 
            #swap
            data[i], data[j] = data[j], data[i] 
            permute(data, i+1, length) 
            data[i], data[j] = data[j], data[i]  


string = "ABC"
n = len(string) 
data = list(string) 
permute(data, 0, n)

1 个答案:

答案 0 :(得分:-1)

Let's break down the code, line by line. We're going to step from the start of the string to the end, incrementing i on each call. Within each call, we iterate j over the remainder of the string.

def permute(data, i, length): 
    # If "i" is at the end, we're done with one permutation: print the result.
    if i==length: 
        print(''.join(data) )

    else:
        # for each remaining character (later in the string)
        for j in range(i,length):

            # Swap that character with the "ith" character
            data[i], data[j] = data[j], data[i]

            # Keeping data[0:i] fixed,
            # generate all permutations of the remainder of the string
            permute(data, i+1, length)

            # Swap the characters back
            data[i], data[j] = data[j], data[i]

Now, add a little basic instrumentation to trace the execution: trace routine entry and recursion; indent every time you recur.

indent = ""

def permute(data, i, length): 
    global indent
    print(indent, "ENTER", ''.join(data), i)
    indent += "  "

    if i==length: 
        print("PERMUATATION:", ''.join(data) )
    else: 
        for j in range(i,length): 
            print(indent, "SWAP", i, j)
            #swap
            data[i], data[j] = data[j], data[i] 
            permute(data, i+1, length) 
            data[i], data[j] = data[j], data[i]  

    indent = indent[2:]


string = "ABC"
n = len(string) 
data = list(string) 
permute(data, 0, n)

OUTPUT:

 ENTER ABC 0
   SWAP 0 0
   ENTER ABC 1
     SWAP 1 1
     ENTER ABC 2
       SWAP 2 2
       ENTER ABC 3
PERMUATATION: ABC
     SWAP 1 2
     ENTER ACB 2
       SWAP 2 2
       ENTER ACB 3
PERMUATATION: ACB
   SWAP 0 1
   ENTER BAC 1
     SWAP 1 1
     ENTER BAC 2
       SWAP 2 2
       ENTER BAC 3
PERMUATATION: BAC
     SWAP 1 2
     ENTER BCA 2
       SWAP 2 2
       ENTER BCA 3
PERMUATATION: BCA
   SWAP 0 2
   ENTER CBA 1
     SWAP 1 1
     ENTER CBA 2
       SWAP 2 2
       ENTER CBA 3
PERMUATATION: CBA
     SWAP 1 2
     ENTER CAB 2
       SWAP 2 2
       ENTER CAB 3
PERMUATATION: CAB

Now trace through the code with this information.