获取vb.net中所有可靠的数组数组合

时间:2013-10-09 19:19:54

标签: arrays vb.net combinations

我在VB.net中有几个数组。这些阵列有不同的长度,我需要它们之间的组合。简单的解决方案是使用嵌套循环,如示例所示:

Dim Array1= {10, 11, 12}
Dim Array2= {15}
Dim Array3= {1,2,3}
Dim array(2) As Object
array(0) = Array1
array(1) = Array2
array(2) = Array3

for (a = 1 to < Array1.Length - 1) 
    for (b = 1 to < Array2.Length - 1) 
        for (c = 1 to < Array3.Length - 1)            
             'Get combination
          Next
      Next
 Next

Output: {10,15,1},{10,15,2},{10,15,3},{11,15,1},{11,15,2},...

但真正的问题是数组的数量不是固定参数(可能是示例中的3或任何其他数字),因此嵌套循环不是解决方案。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

这是我十年前写的一些代码的快速重写,同时仍然使用VB.Net 2003 ...在我的硬盘驱动器中有什么美好的回忆!

希望您发现其输出有用:

10,15,1
10,15,2
10,15,3
11,15,1
11,15,2
11,15,3
12,15,1
12,15,2
12,15,3

生成它的代码:

Public Class Form1

    Private WithEvents FC As ArrayCombinations = Nothing

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        If IsNothing(FC) Then
            FC = New ArrayCombinations
            FC.AddArray(New Integer() {10, 11, 12})
            FC.AddArray(New Integer() {15})
            FC.AddArray(New Integer() {1, 2, 3})
            FC.GenerateCombos()
        End If
    End Sub

    Private Sub FC_combinations(combos As System.Collections.Generic.List(Of System.Collections.Generic.List(Of Integer))) Handles FC.Combinations
        For Each combo As List(Of Integer) In combos
            Debug.Print(String.Join(",", combo.Select(Function(i) i.ToString())))
        Next
        FC = Nothing
    End Sub

End Class

Public Class ArrayCombinations

    Private Arrays As New List(Of Integer())
    Private WithEvents BGW As New System.ComponentModel.BackgroundWorker
    Public Event Combinations(ByVal combos As List(Of List(Of Integer)))

    Public Sub New()
        BGW.WorkerReportsProgress = True
    End Sub

    Public Sub AddArray(ByVal values() As Integer)
        If Not BGW.IsBusy Then
            Arrays.Add(values)
        End If
    End Sub

    Public Sub GenerateCombos()
        If Not BGW.IsBusy Then
            BGW.RunWorkerAsync()
        End If
    End Sub

    Private Sub BGW_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
        Dim sizes As New List(Of Integer)
        Dim combinations As Integer
        Dim remainder As Integer
        Dim quotient As Integer
        Dim combination As List(Of Integer)
        Dim combos As New List(Of List(Of Integer))

        If Arrays.Count > 0 Then
            combinations = 1
            For Each factor() As Integer In Arrays
                sizes.Add(factor.Count)
                combinations = combinations * factor.Count
            Next

            For i As Integer = 0 To combinations - 1
                combination = New List(Of Integer)
                For j As Integer = 1 To Arrays.Count
                    combination.Add(Nothing)
                Next

                quotient = i \ sizes.Item(sizes.Count - 1) ' Integer Division
                remainder = i Mod sizes.Item(sizes.Count - 1)

                combination(Arrays.Count - 1) = Arrays.Item(Arrays.Count - 1)(remainder)
                For j As Integer = (sizes.Count - 2) To 0 Step -1
                    combination.Item(j) = Arrays.Item(j)(quotient Mod sizes.Item(j))
                    quotient = quotient \ sizes.Item(j) ' Integer Division
                Next
                combos.Add(combination)
            Next

            e.Result = combos
        End If
    End Sub

    Private Sub BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
        RaiseEvent Combinations(e.Result)
    End Sub

End Class

答案 1 :(得分:0)

您可以创建一个列表来保存所有数组的组合值,然后将这些值推回到数组中,如下所示:

Dim listCombined = New List(Of Integer)
listCombined.AddRange(array1)
listCombined.AddRange(array2)
listCombined.AddRange(array3)

Dim arrayCombined As Integer() = listCombined.ToArray()

注意:此示例假定您具有整数数组,但您可以将类型更改为数组实际保存的任何类型。您还可以循环遍历数组,而不是逐个列出AddRange调用。