Vb.net all combinations

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-11 07:22:24

问题


I have 6 items which have to be combinated,

items listed: ( this is an example)

  • Ape
  • Cow
  • Deer | Small deer | Big deer
  • sheep

so 'deer' has 2 subitems.

these items are all in an list listed like this:

ape cow {deer | small deer | big deer} sheep

so you can see which item has more items.

what i want is all those combinations:

  • ape cow deer sheep

  • ape cow small deer sheep

  • ape cow big deer sheep

( sometimes there are more then 6 items, sometimes there are less.

Is someone who can help me with this?

EDIT:

Sometimes the list is also something like this:

  • ape
  • cow
  • Deer | Small deer | Big deer
  • sheep
  • mouse | Black mouse | White mouse

( so more items with subitems )


回答1:


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



回答2:


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.




回答3:


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.




回答4:


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


来源:https://stackoverflow.com/questions/7853653/vb-net-all-combinations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!