为什么这个递归有效?有人能告诉我为什么这段代码有效吗?

时间:2014-03-06 21:10:19

标签: vb.net recursion

我对http://visualbasic.about.com/b/2007/06/06/permutations-recursion-and-traversing-a-binary-tree.htm修改过的方法感到茫然不知所措。我在VB.net中重写了它,虽然看起来好像需要大量的循环才能完成任务。

这个方法接受一个单词,并返回该单词中字母的所有变体,沿着它只显示字典中出现的单词的方式,但这不是问题。

一旦通过单词中的字母如abcd,循环通过a,ab,abc等,它就会到达end sub。

我希望它会停止。但事实并非如此,这就是我感到困惑的一点。它返回到递归调用并再次从那里运行代码到end sub,多次。如果有什么我会期望它回到sub的顶部,这本身就是奇怪的,但在递归调用之后不会回到。它不会遍历整个潜艇,看起来就像从那里开始。

SUBSECTION OF CODE

  PermutationOfLetters()
                ' Mark this item free again - start again
                IsItemUsed(i) = False

                ' Restore the current Perm 
                permutationString = PermWord
            End If
        Next
            BGworker.ReportProgress(LoopCounter)
        End Sub

它需要这样做以使分支工作,但我不知道是什么使它做到这一点? 任何人都可以开导我吗?这让人很难解释“巫毒发生在这里”。

我刚注意到链接上的另一张海报,原始代码问了同样的问题。 : - )

所有代码

 Private Sub PermutationOfLetters()
    'Just a counter to see how many time the Sub loops
    Static RecursionCounter As ULong = 0
    '    lbxWords.Items.Add("recursion " & RecursionCounter)
    RecursionCounter += 1

    'Just a counter to count how many loops in the For statement
    Static LoopCounter As ULong = 0


    'chop up the word into a character array w,o,r,d,s
    Static WordIntoletters As Char() = myDictionary.SelectedWord.ToCharArray()


    Static permutationString As String

    ' gives a true /false for each letter as it passes through set false to start - Boolean Array
    Static IsItemUsed(myDictionary.SelectedWord.Length - 1) As Boolean

    Dim PermWord As String = permutationString ' Save the current Perm  for each value currently available

    'count through each letter and operate on those that are false
    For i = 0 To myDictionary.SelectedWord.Length - 1
        LoopCounter += 1

        'when it finds a false then run the loop
        If IsItemUsed(i) = False Then
            'add another letter to the word
            permutationString += WordIntoletters(i)


            If FoundWordsDictionary.ContainsKey(permutationString) = False Then

            End If

            'if words are in the dictionary output real words and are not already saved
            If myDictionary.WordDictionary.ContainsKey(permutationString) = True AndAlso FoundWordsDictionary.ContainsKey(permutationString) = False Then
                '   lbxWords.Items.Add(i & " " & permutationString)
                'pass the words through to the sorted dict for easy output

                FoundWordsDictionary.Add(permutationString, permutationString)
                '  lbxWords.Items.Add(permutationString)
            End If

            ' Mark this item unavailable - finished with a true
            IsItemUsed(i) = True 'so don't come back to that letter

            PermutationOfLetters()
            ' Mark this item free again - start again
            IsItemUsed(i) = False

            ' Restore the current Perm 
            permutationString = PermWord
        End If
    Next
        BGworker.ReportProgress(LoopCounter)
    End Sub

1 个答案:

答案 0 :(得分:2)

您似乎对递归意味着什么感到困惑。当您以递归方式调用方法时,这意味着方法会调用自身。这样做,它就像调用不同的方法时一样。例如:

Public Sub Method1()
    Console.WriteLine("Begin 1")
    Method2()
    Console.WriteLine("End 1")
End Sub

Public Sub Method2()
    Console.WriteLine("2")
End Sub

希望当您在上面的示例中调用Method1时,它将输出以下行并不奇怪:

  

开始1
2
结束1

当执行Method2时,它会继续到下一行(Console.WriteLine("End 1"))。你肯定不希望执行在那时跳回到Method1的顶部。

递归以相同的方式工作,但是在调用堆栈中不是两种不同的方法,而是在调用堆栈中重复多次相同的方法。调用堆栈上方法的每个“实例”都维护它自己的执行位置(这就是为什么它被称为堆栈)。当前对方法的调用状态保持在堆栈中,而对方法的下一次调用则在堆栈上添加。一旦执行完内部方法调用,堆栈就会回退到前一个方法,该方法从中断的位置开始。

对方法的每次调用都有自己的局部变量值的独立副本。虽然在这种情况下,它将许多局部变量定义为Static,这意味着这些变量的值将在调用堆栈中对该方法的所有调用中共享。