Cobold
Cobold

Reputation: 2613

get combinations with repetition

How can I write all possible combinations to the console? For example, if user enters abc, then it will write aaa, aab, aac, abb, abc, acc, bbb, bbc, ccc. Please help me.

Here's some code:

    Dim abc() As String = {"a", "b", "c"} '      

    Sub Main()
        Console.WriteLine("Enter the amount of characters")
        Dim count As Integer = Console.ReadLine
        outputStrings("", count)

        Console.ReadLine()
    End Sub

    Private Sub outputStrings(ByVal startString As String, ByVal letterCount As Integer)
        For i = 0 To abc.Length - 1
            Dim temp As String = startString           
            temp += abc(i)
            If temp.Length = letterCount Then
                Console.WriteLine(temp)

                If i = abc.Length - 1 Then
                    Console.WriteLine("----")    
                End If
            Else
                outputStrings(temp, letterCount)
            End If

        Next
    End Sub

Something has to be done after the dashed lines to remove unwanted permutation to leave out only valid combinations.

Upvotes: 1

Views: 1281

Answers (4)

Carlos Borau
Carlos Borau

Reputation: 1473

Amazing code from here:

Private Shared Function PermutationsWithRepetition(Of T)(list As IEnumerable(Of T), length As Integer) As IEnumerable(Of IEnumerable(Of T))
        If length = 1 Then
            Return list.[Select](Function(x) New T() {x})
        End If
        Return PermutationsWithRepetition(list, length - 1).SelectMany(Function(x) list, Function(t1, t2) t1.Concat(New T() {t2}))
    End Function

Can be used with Integer, Char, Double etc. Example of use:

Dim myarray(1) As Integer
myarray(0) = 1
myarray(1) = 2
Dim k As Integer = 2 'number of "slots" to do the permutations

mypermutations = PermutationsWithRepetition(myarray,k)

For Each row As IEnumerable(Of Integer) In mypermutations
            Console.WriteLine("")
            For Each col As IntegerIn row
                Console.Write(col.toString())
            Next            
Next

Output:

11 12 21 22

Upvotes: 0

btilly
btilly

Reputation: 46389

You just need to make a recursive call there.

Dim abc() As String = {"a", "b", "c"} '      

Sub Main()
    Console.WriteLine("Enter the amount of characters")
    Dim count As Integer = Console.ReadLine
    outputStrings("", count)

    Console.ReadLine()
End Sub

Private Sub outputStrings(ByVal startString As String, ByVal letterCount As Integer)
    For i = 0 To abc.Count - 1
        Dim temp As String = startString           
        temp += abc(i)
        If temp.Length = letterCount Then
            Console.WriteLine(temp)
        Else
            outputStrings(temp, letterCount)
        End If

    Next
End Sub

Do note that if someone enters a negative number that your code will run forever. I'll leave fixing that as an easy exercise.

Upvotes: 0

fgb
fgb

Reputation: 18569

You can restrict the letters used to ones at or to the right of abc(i) with an additional parameter abcIndex, and start the for loop from there. Only strings which have their letters in alphabetical order will be written, which prevents duplicates.

Private Sub outputStrings(ByVal startString As String, ByVal letterCount As Integer, ByVal abcIndex As Integer)
    For i = abcIndex To abc.Length - 1
        Dim temp As String = startString
        temp += abc(i)
        If temp.Length = letterCount Then
            Console.WriteLine(temp)
        Else
            outputStrings(temp, letterCount, i)
        End If
    Next
End Sub

Call with:

outputStrings("", 3, 0)

Upvotes: 1

dfb
dfb

Reputation: 13289

def go(chars,thusfar):
    if len(thusfar) = len(chars):
        print thusfar
    for char in chars:
        go(chars,thusfar+char);

This should be easy enough to translate to VB (read: I don't know VB)

Upvotes: 1

Related Questions