Jak powinienem ustawić stan (wszystkie permutacje 3 z zestawu 5) dowolnej 2 z 5 itd.

Jeśli mam:

Me.TextBox1.Text = String.Join(Environment.NewLine, Permutation.Create({"1"c, "2"c, "3"c, "4"c, "5"c}, sort:=False))

Wyjście: (Tysiąc pokazuje mi permutacji 5 z 5).)

12345
12354
12435
12453
12534 and so on...

Oczekiwany wyjście: Wartość = 3 (wszystkie permutacje 3 z zestawu 5.

123
124
125 
and so on...

Jak powinienem ustawić ten warunek?

Public NotInheritable Class Permutation

    Public Shared Function Create(array As Char()) As List(Of String)
        Return Permutation.Create(array, False)
    End Function

    Public Shared Function Create(array As Char(), sort As Boolean) As List(Of String)
        If (array Is Nothing) Then
            Throw New ArgumentNullException("array")
        ElseIf ((array.Length < 0) OrElse (array.Length > 13)) Then
            Throw New ArgumentOutOfRangeException("array")
        End If
        Dim list As New List(Of String)
        Dim n As Integer = array.Length
        Permutation.Permute(list, array, 0, array.Length)
        If (sort) Then
            list.Sort()
        End If
        Return list
    End Function

    Private Shared Sub Permute(list As List(Of String), array As Char(), start As Integer, n As Integer)
        Permutation.Print(list, array, n)
        If (start < n) Then
            Dim i, j As Integer
            For i = (n - 2) To start Step -1
                For j = (i + 1) To (n - 1)
                    Permutation.Swap(array, i, j)
                    Permutation.Permute(list, array, (i + 1), n)
                Next
                Permutation.RotateLeft(array, i, n)
            Next
        End If
    End Sub

    Private Shared Sub Print(list As List(Of String), array As Char(), size As Integer)
        If (array.Length <> 0) Then
            Dim s As Char() = New Char(size - 1) {}
            For i As Integer = 0 To (size - 1)
                s(i) = array(i)
            Next
            list.Add(s)
        End If
    End Sub

    Private Shared Sub RotateLeft(array As Char(), start As Integer, n As Integer)
        Dim tmp As Char = array(start)
        For i As Integer = start To (n - 2)
            array(i) = array(i + 1)
        Next
        array(n - 1) = tmp
    End Sub

    Private Shared Sub Swap(array As Char(), i As Integer, j As Integer)
        Dim tmp As Char
        tmp = array(i)
        array(i) = array(j)
        array(j) = tmp
    End Sub

End Class

Ze względu na Int32.MaxValue limit tej klasy będzie wspierać poziomy od 1 do 13.

s=1, n=1
s=2, n=2
s=3, n=6
s=4, n=24
s=5, n=120
s=6, n=720
s=7, n=5040
s=8, n=40320
s=9, n=362880
s=10, n=3628800
s=11, n=39916800
s=12, n=479001600
s=13, n=6227020800

Zastosowanie: Me.TextBox1.Text = String.Join(Environment.NewLine, Permutation.Create({"c"c, "f"c, "a"c, "m"c}, sort:=False))

0
Martin Dorin 17 grudzień 2019, 11:30

1 odpowiedź

Najlepsza odpowiedź

Możesz to zrobić z rekurencją:

Sub Main()
    Dim result = GetCombinations({"1"c, "2"c, "3"c, "4"c, "5"c}.ToList(), 3)

    For Each item In result
        Console.WriteLine(String.Concat(item))
    Next
End Sub

Private Function GetCombinations(Of T)(sourceList As IEnumerable(Of T), length As Integer) As IEnumerable(Of IEnumerable(Of T))
    If length = 1 Then Return sourceList.[Select](Function(x) New T() {x})
    Return GetCombinations(sourceList, length - 1).SelectMany(Function(x) sourceList, Function(x1, x2) x1.Concat(New T() {x2}))
End Function

Funkcja GetCombinations() działa poprzez uzyskanie wszystkich kombinacji, które są mniej długości, że bieżąca długość listy. Rekurencyjnie robi to, dopóki nie ma długości listy 1 - w której punkcie przestaje rekurzeć.

Aby uzyskać przecinek wyjściowy rozliczany, używaj czegoś takiego:

For Each item In result
    Console.WriteLine(String.Join(",", item))
Next

Aby zmienić długość ciągu wyjściowego, zmień instancję początkową do GetCombinations(), aby uzyskać 2 znaki znaków użytkowych:

Dim result = GetCombinations({"1"c, "2"c, "3"c, "4"c, "5"c}.ToList(), 2)
0
theduck 17 grudzień 2019, 09:57