Vb.net所有组合

时间:2011-10-21 18:24:55

标签: vb.net combinations

我有6件需要组合的物品,

列出的项目:(这是一个例子)

  • 鹿|小鹿|大鹿
  • 绵羊

所以'鹿'有2个子项目。

这些项目都列在这样列出的列表中:

猿 牛 {鹿|小鹿|大鹿} 羊

这样您就可以看到哪个项目包含更多项目。

我想要的就是所有这些组合:

  • 猿 牛 鹿 羊

  • 猿 牛 小鹿 羊

  • 猿 牛 大鹿 羊

(有时会有超过6项,有时会有更少。

有人可以帮我解决这个问题吗?

编辑:

有时列表也是这样的:

  • 鹿|小鹿|大鹿
  • 绵羊
  • 鼠标|黑老鼠|白老鼠

(所以更多项目有子项目)

4 个答案:

答案 0 :(得分:1)

您需要我的解决方案的变体,我在HERE in this solution中提出了类似的问题。也许它足以帮助你?

也许你不被允许看到答案,所以我把它复制到这里。有人想要1和2的所有组合串联长度为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

您需要将数字值设置为1,2等,而不是数字本身,并为每个子列表创建类似的操作。

答案 1 :(得分:1)

我不能对@Martin提供的方法发表评论,因为我不是专家交换的成员,但这是我将如何处理这个问题。

你想要一个IEnumerable(IEnumerable(of T))

当你有“猿”时,你需要把它想象成{Ape}。这就是你的清单:

{猿} {牛}, {鹿,小鹿,大鹿}, {羊}

从那里,您可以通过对外部列表进行分组并遍历内部列表来构建组合。

即。第一项{Ape}只有一个元素,所以你只会迭代一次。与{Cow}相同,但是所有鹿的第三次将被重复3次。

这应该足以让你开始。

答案 2 :(得分:0)

这是VB 2010的递归解决方案(当有很多组合时,可能性能不是很好,但它是一个开始):

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

测试代码:

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

测试输出:

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

答案 3 :(得分:0)

想要输入为字符串吗?没有递归?那么这是最终解决方案,简单改编我以前的样本:

    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