0

これがどのように見えるべきかの例です(これはコードが使用するのと同じ例です) ここに画像の説明を入力

レベル 1 からレベル 2 に変更するとコードがおかしくなり始め、大きな混乱が発生します。まったく理解できません。

ここにコードがあります

   Public Class Node
        Public label As Byte
        Public visited As Boolean = False
        Public level As Integer

        Public Sub New(ByVal label As Byte, ByVal level As Integer)
            Me.label = label
            Me.level = level
        End Sub
    End Class

    Public rootNodes As New List(Of Node)
    Public nodes As New List(Of Node)
    Dim adjMatrix As Byte(,)
    Dim setDimensions As Boolean = False

    Public Sub connectNode(ByVal start As Node, ByVal endd As Node)
        'This method will be called to make connect two nodes
        If setDimensions = False Then
            ReDim Preserve adjMatrix(999 - 1, 999)
            setDimensions = True
        End If
        Dim startIndex As Integer = nodes.IndexOf(start)
        Dim endIndex As Integer = nodes.IndexOf(endd)
        adjMatrix(startIndex, endIndex) = 1
        adjMatrix(endIndex, startIndex) = 1
    End Sub

    Private Function getUnvisitedChildNode(ByVal n As Node) As Node
        Dim index As Integer = nodes.IndexOf(n)
        Dim j As Integer = 0

        Do While j < nodes.Count
            If adjMatrix(index, j) = 1 AndAlso nodes(j).visited = False Then
                Return nodes(j)
            End If
            j += 1
        Loop
        Return Nothing
    End Function

    Private Sub clearNodes()
        For Each n As Node In nodes
            n.visited = False
        Next
    End Sub

    Private Sub printNode(ByVal n As Node)
        Debug.Print(n.label & " ")
    End Sub

    Public Enum Operation
        LessThan = 0
        GreaterThan = 1
    End Enum

    Public Function getPossibleNumbersForFirstByte(ByVal op As Operation, ByVal operationOf As Byte, ByVal numbersAlreadyUsed As List(Of Byte), ByVal totalSize As Long) As List(Of Byte)
        Dim possibleNumbers As New List(Of Byte)
        Dim tempNumber As Integer = -1

        While True
            If op = Operation.LessThan Then
                tempNumber = IIf(tempNumber = -1, operationOf - 1, tempNumber - 1)
            ElseIf op = Operation.GreaterThan Then
                tempNumber = IIf(tempNumber = -1, operationOf + 1, tempNumber + 1)
            End If

            If tempNumber < 1 OrElse tempNumber > totalSize Then
                Exit While
            End If
            If numbersAlreadyUsed Is Nothing OrElse numbersAlreadyUsed.Contains(tempNumber) = False Then
                possibleNumbers.Add(tempNumber)
            End If
        End While
        Return possibleNumbers
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        test()
    End Sub

   Sub test()
        'Dim actualNumbers() As Byte = {5, 6, 1, 9, 7, 3, 8, 2, 4, 10}

        Dim actualNumberList As New List(Of Byte)
        actualNumberList.AddRange({5, 6, 1, 9, 7, 3, 8, 2, 4, 10})
        Dim ListofGTLT() As Byte = {1, 0, 1, 0, 0, 1, 0, 1, 1}

        Dim firstNumber As Byte = actualNumberList(0)
        Dim possibleNumbersToUse As New List(Of Byte)
        Dim numbersAlreadyUsed As New List(Of Byte)

        For currentLevel = 0 To UBound(ListofGTLT)
            'clear visited nodes.
            clearNodes()

            If currentLevel = 0 Then
                'Generates Level 0 of all possible values in the first offset.
                possibleNumbersToUse = getPossibleNumbersForFirstByte(ListofGTLT(currentLevel), firstNumber, Nothing, 10)
                Dim n As Node
                'Generates parent nodes of all possible values in the first offset.
                For Each possibleNumber As Byte In possibleNumbersToUse
                    n = New Node(possibleNumber, 0)
                    rootNodes.Add(n)
                    nodes.Add(n)
                Next
            Else
                Dim rootNode As Node
                For Each rootNode In rootNodes
                    'Clear numbers already used.
                    numbersAlreadyUsed.Clear()
                    'Set already exists first value (known value).
                    numbersAlreadyUsed.Add(firstNumber)

                    If currentLevel = 1 Then
                        'Gets all the numbers which are possible connections.
                        possibleNumbersToUse = getPossibleNumbersForFirstByte(ListofGTLT(currentLevel), rootNode.label, numbersAlreadyUsed, 10)

                        Dim n As Node
                        'Setup connections with new nodes to root node.
                        For Each value As Byte In possibleNumbersToUse
                            n = New Node(value, 1)
                            nodes.Add(n)
                            'Debug.Print("[Connection]: " & rootNode.label & " = " & n.label)
                            connectNode(rootNode, n)
                        Next
                    Else
                        numbersAlreadyUsed.Add(rootNode.label)

                        Dim child = getUnvisitedChildNode(rootNode)
                        Do While child IsNot Nothing
                            Debug.Print("------------------------------------------")
                            Debug.Print("| Root = " & rootNode.label)
                            Debug.Print("| Child Level = " & child.level)
                            Debug.Print("| Child = " & child.label)
                            Debug.Print("------------------------------------------")

                            'Add to already existing values the child connection node.
                            If numbersAlreadyUsed.Contains(child.label) = False Then
                                If child.level = (currentLevel - 1) Then
                                    'Gets next possible numbers which are possible connections.
                                    possibleNumbersToUse = getPossibleNumbersForFirstByte(ListofGTLT(currentLevel), child.label, numbersAlreadyUsed, 10)

                                    Dim n As Node
                                    'Setup connections with new nodes to child node.
                                    For Each value As Byte In possibleNumbersToUse
                                        n = New Node(value, currentLevel)
                                        nodes.Add(n)
                                        connectNode(child, n)
                                    Next

                                    If child.level = 1 Then
                                        'Finish all the level 1 childs for the current Root Node.
                                        child.visited = True
                                        child = getUnvisitedChildNode(rootNode)
                                        Continue Do
                                    Else
                                        numbersAlreadyUsed.Add(child.label)
                                        child.visited = True
                                        child = getUnvisitedChildNode(child)
                                        Continue Do
                                    End If

                                Else
                                    numbersAlreadyUsed.Add(child.label)
                                    child.visited = True
                                    child = getUnvisitedChildNode(child)
                                    Continue Do
                                End If
                            Else
                                numbersAlreadyUsed.Add(child.label)
                                child.visited = True
                                child = getUnvisitedChildNode(child)
                                Continue Do
                            End If
                        Loop
                    End If
                Next
            End If
        Next
    End Sub
4

1 に答える 1

1

独自のクラスを実装する代わりに、このために設計された TreeNode クラスを使用すると、コードがはるかに理解しやすくなり、TreeView にネイティブであるという利点が追加されます。つまり、基本ノードを追加するだけで済みます。そして ExpandAll を呼び出すと、ツリーのグラフィカル表現が得られます。また、やりたいことは再帰ルーチンに適しています。ツリー構造を構築する方法を次に示します。子ノードが追加されるたびに、ツリー内ですでに値が上にあるものはスキップされます。

    Private Sub btnAnswers_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        'Declare initial treenode with the value we want.
        Dim Tree As New TreeNode("5")
        'Declare the string of bits.
        Dim input As String = "1001001001"
        'Start the recursive routine
        CalculateTreeNodes(Tree, input)
        'Show the tree
        TreeView1.Nodes.Add(Tree)
        TreeView1.ExpandAll()h
    End Sub
    Private Sub CalculateTreeNodes(CurrentNode As TreeNode, directions As String)
        If directions = "" Then Return
        'Parse the text of the current node as byte
        Dim value As Byte = Byte.Parse(CurrentNode.Text)
        'Get the direction we want and truncate the string
        Dim direction As Directions = CType([Enum].Parse(GetType(Directions), directions(0).ToString), Directions)
        If directions.Length > 0 Then
            directions = directions.Substring(1)
        End If
        'Get a list of the values of all the parent nodes above this one.
        Dim Values As New List(Of Byte)
        GetPrevValues(CurrentNode, Values)
            'build our child nodes based on the direction we want.
            Select Case direction
                Case WindowsApplication7.Directions.Higher
                    For i As Byte = value + 1 To 10
                    If Not Values.Contains(i) Then
                        Dim node As New TreeNode(i.ToString)
                        CurrentNode.Nodes.Add(node)
                        'Calculate the children for each node
                        CalculateTreeNodes(node, directions)
                    End If
                    Next
                Case WindowsApplication7.Directions.Lower
                    For i As Byte = 1 To value - 1
                    If Not Values.Contains(i) Then
                        Dim node As New TreeNode(i.ToString)
                        CurrentNode.Nodes.Add(node)
                        CalculateTreeNodes(node, directions)
                    End If
                    Next
            End Select
    End Sub
    'recursive routine to find the parent values.
    Private Sub GetPrevValues(CurrentNode As TreeNode, Values As List(Of Byte))
        If Not CurrentNode Is Nothing Then
            Values.Add(Byte.Parse(CurrentNode.Text))
            GetPrevValues(CurrentNode.Parent, Values)
        End If
    End Sub
End Class
Public Enum Directions
    Higher = 1
    Lower = 0
End Enum

最長の分岐を見つけるには、条件を使用directionsして 1 文字までかどうかを確認できます。その後、すべての子が最長の分岐に含まれます。

于 2013-07-29T06:58:28.817 に答える