2017-02-24 91 views
1

我需要找出一种方法来输出结果的所有组合的行数(最好,如果可能在一个单一行)Excel vba如何将数字输出组合到Excel行?

我有8位数{1,2,3,4,5, 6,7,8}组合的典型输出是i; j(i,j是来自集合的数字,如果选择两个,则为i < j)。生成结果很简单:

Dim Myarray_2 As String 
    Dim sht as Worksheet 
    set sht = Sheet1 

    Myarray_2 = ""   ' pick up 2 out of 8 
    For j = 2 To 8 
     For i = 1 To j - 1 
     sht.Cells(i + 1, j + 1) = Str(MyArray(i)) + ";" + Str(MyArray(j)) 
      Myarray_2 = Myarray_2 + Str(MyArray(i)) + ";" + Str(MyArray(j)) + "|" 
     Next i 
    Next j 

这是拿起2的例子,我已经将它输出到工作表的行。

我也有解决方案,拿起3,现在我的问题是其余的情况下,如何得到输出?

下面是用于拾取3溶液:

Dim Myarray_3 As String 
     Myarray_3 = ""   ' 3 out of 8 
    k = 3 
    Do While k >= 3 And k <= 8 
    'inner loop through i j 
     For j = 2 To k - 1 
      For i = 1 To j - 1 
       sht.Cells(i + 11, j - 1 + m) = Str(MyArray(i)) + ";" + Str(MyArray(j)) + ";" + Str(MyArray(k)) 
       Myarray_3 = Myarray_3 + Str(MyArray(i)) + ";" + Str(MyArray(j)) + ";" + Str(MyArray(k)) + "|" 
      Next i 
     Next j 

    k = k + 1 
    m = m + 7 
    Loop 

通过MYARRAY(ⅰ)被初始化为MYARRAY(i)所述的方式= I

+0

是'1,2'和'2,1'是一回事吗?如果是这样,嵌套循环会做到这一点。 – Jeeped

+0

+0

我会一直说的第一件事就是在数组中做你的组合工作。然后在最后输出数组.. – MacroMarc

回答

0

我发现一些代码,我从另一个有好的程序员,我改变了代码以适应你的问题。如果您将N设为您的set/array的成员数量,那么您将拥有(2^N)-1组合,但是您可以使用自己的条件对其进行过滤。请注意,在您的问题中,使用您的条件进行过滤时,成员的顺序将非常重要。

该代码将首先生成所有组合,然后应用条件。数组结果将是主输出,因此它的大小将始终为(2^N)-1。阵列结果 - 过滤将是你想要的。

请注意,如果您有从左到右排序的数字,数组Result和Result_filtered将是相同的。

您可以将任何格式的输出打印到任何工作表中。

该方法使用按位计算,以获得组合:

如果N = 2,则数comnibations的将是(2^2)-1 = 3 我们总是排除0”当然 {的二进制A,B} - > {[00],[01],[10],[11]} - > {ignore,[B],[A],[AB]}

我希望这有助于!如果没有,请打对勾这个前面回答

运行子测试:

Sub Test() 
    Dim bCondSatisfied As Boolean 
    Dim InxComb As Integer 
    Dim InxResult As Integer 
    Dim count As Integer 
    Dim i As Integer 
    Dim j As Integer 
    Dim arr() As String 
    Dim TestData() As Variant 
    Dim Result() As Variant 
    Dim Result_filtered() As Variant 

    TestData = Array(1, 3, 2, 4) 

    Call GenerateCombinations(TestData, Result) 

    'Now you have all the possible combinations, you can apply custom conditions 
    '(e.g. any number on the left side of another number should be smaller, practically this is satisfied with the 
    ' given test array, but if the numbers are scrambled it will fix the problem) 
    ReDim Result_filtered(0 To 0) 
    Result_filtered(0) = "No Combination Matched the Condition" 'default for the case there is no result matched 

    count = 0 
    For i = 0 To UBound(Result) 
     arr() = Result(i) 
     bCondSatisfied = True 
     If UBound(arr) > 0 Then 'if there is more than one number in the array, compare the adjacent numbers 
      For j = 0 To UBound(arr) - 1 
       If arr(j) > arr(j + 1) Then 
       bCondSatisfied = False 
       Exit For 
       End If 
      Next j 
     End If 

     'Store the array in the filtered array if it passed the test 
     If bCondSatisfied = True Then 
      ReDim Preserve Result_filtered(count) 
      Result_filtered(count) = arr 
      count = count + 1 
     End If 
    Next i 


    'Print Result 
    For InxResult = 0 To UBound(Result) 
    Debug.Print Right(" " & InxResult + 1, 3) & " "; 
    For InxComb = 0 To UBound(Result(InxResult)) 
     Debug.Print "[" & Result(InxResult)(InxComb) & "] "; 
    Next 
    Debug.Print 
    Next 

    Debug.Print "-----------------" 'separate two results 

    'Print Result_filtered 
    For InxResult = 0 To UBound(Result_filtered) 
    Debug.Print Right(" " & InxResult + 1, 3) & " "; 
    For InxComb = 0 To UBound(Result_filtered(InxResult)) 
     Debug.Print "[" & Result_filtered(InxResult)(InxComb) & "] "; 
    Next 
    Debug.Print 
    Next 

End Sub 

Sub GenerateCombinations(ByRef AllFields() As Variant, _ 
              ByRef Result() As Variant) 

    Dim InxResultCrnt As Integer 
    Dim InxField As Integer 
    Dim InxResult As Integer 
    Dim i As Integer 
    Dim NumFields As Integer 
    Dim Powers() As Integer 
    Dim ResultCrnt() As String 

    NumFields = UBound(AllFields) - LBound(AllFields) + 1 

    ReDim Result(0 To 2^NumFields - 2) ' one entry per combination 
    ReDim Powers(0 To NumFields - 1)   ' one entry per field name 

    ' Generate powers used for extracting bits from InxResult 
    For InxField = 0 To NumFields - 1 
    Powers(InxField) = 2^InxField 
    Next 

For InxResult = 0 To 2^NumFields - 2 
    ' Size ResultCrnt to the max number of fields per combination 
    ' Build this loop's combination in ResultCrnt 
    ReDim ResultCrnt(0 To NumFields - 1) 
    InxResultCrnt = -1 
    For InxField = 0 To NumFields - 1 
     If ((InxResult + 1) And Powers(InxField)) <> 0 Then 
     ' This field required in this combination 
     InxResultCrnt = InxResultCrnt + 1 
     ResultCrnt(InxResultCrnt) = AllFields(InxField) 
     End If 
    Next 
    ' Discard unused trailing entries 
    ReDim Preserve ResultCrnt(0 To InxResultCrnt) 
    ' Store this loop's combination in return array 
    Result(InxResult) = ResultCrnt 
    Next 

End Sub