-1

I need a code that could give me a list of unique combinations from a set of elements in an array, something like this:

Say myArray contains [A B C]
So, the output must be:

A
B
C
A B
A C
B C
A B C

or

A B C
B C
A C
A B
A
B
C

either output is OK for me (Starts with 1 combination, followed by 2 combinations and ends with all combination OR vice versa).
The position of the letters are not critical and the order of letters within the same combination type is also not critical.

I'd found a suggestion by 'Dick Kusleika' in a thread: Creating a list of all possible unique combinations from an array (using VBA) but when I tried, it did not present me with the arrangement that I wanted.

I'd also found a suggestion by 'pgc01' in a thread: http://www.mrexcel.com/forum/excel-questions/435865-excel-visual-basic-applications-combinations-permutations.html and it gave me the arrangement that I wanted however, the combinations was not being populated in an array but it was being populated in excel cells instead, using looping for each combination.

So, I wanted the arrangement of combinations to be like what 'pgc01' suggested and being populated in an array as what 'Dick Kusleika' presented.

Anyone can help? Appreciate it.

2
  • Do you want the output in worksheet cells? Commented Nov 29, 2014 at 12:24
  • Dear Gary's Student, No, I wanted the output to be in an array first, once the output is 'kept' in the array, I will have other manipulation after that. As I mentioned in my questions, I did find one solution, but after I worked out with the solution, the arrangement of the combinations was not as what I wanted. Appreciate your help Gary's Student. Commented Nov 29, 2014 at 14:46

1 Answer 1

0

Start from here:

Sub TestRoutine()
    Dim inputt() As String, i As Long
    Dim outputt As Variant
    inputt = Split("A B C", " ")
    outputt = Split(ListSubsets(inputt), vbCrLf)
    For i = LBound(outputt) + 2 To UBound(outputt)
        MsgBox i & vbTab & outputt(i)
    Next i
End Sub


Function ListSubsets(Items As Variant) As String
    Dim CodeVector() As Long
    Dim i As Long
    Dim lower As Long, upper As Long
    Dim SubList As String
    Dim NewSub As String
    Dim done As Boolean
    Dim OddStep As Boolean

    OddStep = True
    lower = LBound(Items)
    upper = UBound(Items)

    ReDim CodeVector(lower To upper) 'it starts all 0
    Do Until done
        'Add a new subset according to current contents
        'of CodeVector

        NewSub = ""
        For i = lower To upper
            If CodeVector(i) = 1 Then
                If NewSub = "" Then
                    NewSub = Items(i)
                Else
                    NewSub = NewSub & " " & Items(i)
                End If
            End If
        Next i
        If NewSub = "" Then NewSub = "{}" 'empty set
        SubList = SubList & vbCrLf & NewSub
        'now update code vector
        If OddStep Then
            'just flip first bit
            CodeVector(lower) = 1 - CodeVector(lower)
        Else
            'first locate first 1
            i = lower
            Do While CodeVector(i) <> 1
                i = i + 1
            Loop
            'done if i = upper:
            If i = upper Then
                done = True
            Else
                'if not done then flip the *next* bit:
                i = i + 1
                CodeVector(i) = 1 - CodeVector(i)
            End If
        End If
        OddStep = Not OddStep 'toggles between even and odd steps
    Loop
    ListSubsets = SubList
End Function

Note we discard the first two elements of the output array.

Sign up to request clarification or add additional context in comments.

6 Comments

Dear Gary's Student, appreciate your fast feedback. Let me give it a go. I'll come back to you. Thanks.
Dear Gary's Student. Appreciate your codes. I've ran your code, but the combination list that they produce was not as what I wanted. Perhaps, it could produce something like this: outputt(0) = "", outputt(1)= "{}", outputt(2)="A", outputt(3)="B", outputt(4)="C", outputt(5)="AB", outputt(6)="BC", outputt(7)="AC", outputt(8)="ABC". It is possible?
Or, the output could be starts from "ABC" down to "A"... Appreciate your expertise Gary's Student.
Not necessarily, it is just the ARRANGEMENT that not meet to what I wanted. What I meant by ARRANGEMENT is, the output could be in the form of: [A,B,C,AB,AC,BC,ABC], or [B,C,A,BA,BC,AC,ABC], or [C,B,A,AB,AC,BC,CBA] or [A,C,B,CA,CB,BA,BAC] or any set that have the similar ARRANGEMENT. The first three set must be of a 'one alphabet' (could be A,B,C or C,B,A or B,C,A or B,A,C or similar), the followed by the second three sets that must be of a 'two pair alphabets' (could be AB,AC,BC or BA,CA,CB or BC,AC,AB or any similar type) and ends with '3 alphabets'-could be ABC or CBA or BCA or BAC etc.
This is a COMBINATION set, NOT PERMUTATION set. Meaning, combination of AB=BA, AC=CA, BC=CB, ABC=CBA=BCA=ACB. This is what I meant by 'Order not critical'. I am Sorry if I'm using the wrong word in my question that confuses you (English is not my first language).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.