Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have several arrays in VB.net. These arrays have different lengths and I need the combination between them. The simple solution is using nested loop as in the example:

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},...

But the real problem is that the number of arrays is not a fixed parameter (could be 3 as in the example or any other number) and therefore nested loops is not a solution.

Any idea?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
469 views
Welcome To Ask or Share your Answers For Others

1 Answer

Here's a quick rewrite of some code I wrote almost a decade ago while still using VB.Net 2003...what great memories lying around in my hard drive!

Hope you find its output useful:

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

The code that generated it:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...