Vb.net all combinations

前端 未结 4 1105
南旧
南旧 2021-01-16 16:18

I have 6 items which have to be combinated,

items listed: ( this is an example)

  • Ape
  • Cow
  • Deer | Small deer | Big deer
相关标签:
4条回答
  • 2021-01-16 16:31

    Want the input as strings? and no recursion? then here's the final solution, a simple adaptation of my previous sample:

        Dim Lines As New List(Of List(Of String))
        AddItem(Lines, "a ")
        AddItem(Lines, "b ")
        AddItem(Lines, "c1|c2|c3 ")
        AddItem(Lines, "d ")
        AddItem(Lines, "e1|e2")
        AddItem(Lines, "f ") ' etc
        Dim i As Integer
        Dim j As Integer
        Dim ItemnrInLine(Lines.Count - 1) As Integer
        Dim NrCombinations = 1
        For i = 0 To (Lines.Count - 1)
            ItemnrInLine(i) = 0
            NrCombinations *= Lines(i).Count
        Next
        ItemnrInLine(Lines.Count - 1) = -1 ' to get first combination as solution
        For i = 1 To NrCombinations
            ItemnrInLine(Lines.Count - 1) += 1
            For j = Lines.Count - 1 To 0 Step -1
                If ItemnrInLine(j) = Lines(j).Count Then
                    ItemnrInLine(j) = 0
                    ItemnrInLine(j - 1) += 1
                End If
            Next
            printOut(Lines, ItemnrInLine)
        Next
    
    Sub printOut(ByVal Lines As List(Of List(Of String)), ByVal ItemnrInLine() As Integer)
        Dim Result As String = ""
        For k = 0 To Lines.Count - 1
            Result = Result & Lines(k)(ItemnrInLine(k)).Trim & " "
        Next
        Debug.WriteLine(Result)
    End Sub
    
    Sub AddItem(ByVal Lines As List(Of List(Of String)), ByVal inputString As String)
        Dim words() As String = inputString.Split("|"c)
        Dim wordList As New List(Of String)
        For i As Integer = 0 To words.Count - 1
            wordList.Add(words(i))
        Next
        Lines.Add(wordList)
    End Sub
    
    0 讨论(0)
  • 2021-01-16 16:43

    Here's a recursive solution for VB 2010 (probably not very good performance-wise when there are a lot of combinations, but it's a start):

    Function GetCombinations(items As String()(), Optional index As Integer = 0) As List(Of String())
        Dim combinations As New List(Of String())
        Dim lastIndex = items.Count - 1
        Select Case index
            Case Is < 0, Is > lastIndex
                Throw New ArgumentException("index should be 0 or greater")
            Case lastIndex
                For Each item In items(index)
                    combinations.Add({item})
                Next
            Case Else
                Dim nextCombinations = GetCombinations(items, index + 1)
                For Each item In items(index)
                    For Each nextCombination In nextCombinations
                        combinations.Add({item}.Concat(nextCombination).ToArray)
                    Next
                Next
        End Select
        Return combinations
    End Function
    

    Test code:

    Dim items = {({"Ape"}), ({"Cow"}), ({"Deer", "Small deer", "Big deer"}), ({"Sheep"}), ({"Mouse", "Black Mouse", "White mouse"})}
    For Each combination In GetCombinations(items)
        Console.WriteLine(String.Join(", ", combination))
    Next
    

    Test outputs:

    Ape, Cow, Deer, Sheep, Mouse
    Ape, Cow, Deer, Sheep, Black Mouse
    Ape, Cow, Deer, Sheep, White mouse
    Ape, Cow, Small deer, Sheep, Mouse
    Ape, Cow, Small deer, Sheep, Black Mouse
    Ape, Cow, Small deer, Sheep, White mouse
    Ape, Cow, Big deer, Sheep, Mouse
    Ape, Cow, Big deer, Sheep, Black Mouse
    Ape, Cow, Big deer, Sheep, White mouse
    
    0 讨论(0)
  • 2021-01-16 16:51

    I can't comment on the approach @Martin supplied as I'm not a member of Experts Exchange, but here is how I would approach the problem.

    You want an IEnumerable (of IEnumerable (of T))

    When you have "Ape", you need to think of it as {Ape}. That makes your list:

    {Ape}, {Cow}, {Deer, Small deer, Big deer}, {sheep}

    From there, you build your combinations by grouping the outer list and iterating through the inner list(s).

    I.E. The first item {Ape} only has one element, so you would only iterate on that once. The same with {Cow}, but the third with all the deer would be iterated over 3 times.

    That should be enough to get you started.

    0 讨论(0)
  • 2021-01-16 16:53

    You will need a variant of my solution, that I presented in HERE in this solution for a similar problem. maybe it suffices to get you along?

    Perhaps you're not allowed to see the answer, so I copy it here. Someone wanted all combinations of 1 and 2 in series with length 3

       Dim HighestValue As Integer = 2 ' max value
        Dim NrOfValues As Integer = 3 ' nr of values in one result
        Dim Values(NrOfValues) As Integer
        Dim i As Integer
        For i = 0 To NrOfValues - 1
            Values(i) = 1
        Next
        Values(NrOfValues - 1) = 0 ' to generate first as ALL 1
        For i = 1 To HighestValue ^ NrOfValues
            Values(NrOfValues - 1) += 1
            For j As Integer = NrOfValues - 1 To 0 Step -1
                If Values(j) > HighestValue Then
                    Values(j) = 1
                    Values(j - 1) += 1
                End If
            Next
            Dim Result As String = ""
            For j As Integer = 0 To NrOfValues - 1
                Result = Result & CStr(Values(j))
            Next
            Debug.WriteLine(Result)
        Next
    

    You will need to put arrayvalues indexed by 1, 2, etc instead of the numbers itself, and invent a similar operation for each sublist.

    0 讨论(0)
提交回复
热议问题