Пошаговый порядок перестановок на основе предоставленного числа - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть 5 элементов, которые можно разместить в любом уникальном порядке, я хочу сохранить значения (числа) одного уникального порядка в переменной, один за другим. Например:

Ввод пользователя: 7

Тогда i_Int = 7

должен дать мне

v_Var = 1

подождите 1 сек

v_Var = 3

подождите 1 сек

v_Var = 2

подождите 1 сек

v_Var = 4

подождите 1 сек

v_Var = 5

В приведенных ниже данных перечислены все возможные перестановки из 5 элементов, где в первой строке перечислены перестановки #, у меня не будет этих данных, чтобы упростить задачу.

1   1   2   3   4   5
2   1   2   3   5   4
3   1   2   4   3   5
4   1   2   4   5   3
5   1   2   5   3   4
6   1   2   5   4   3
7   1   3   2   4   5
8   1   3   2   5   4
9   1   3   4   2   5
10  1   3   4   5   2
...
111 5   3   2   1   4
112 5   3   2   4   1
113 5   3   4   1   2
114 5   3   4   2   1
115 5   4   1   2   3
116 5   4   1   3   2
117 5   4   2   1   3
118 5   4   2   3   1
119 5   4   3   1   2
120 5   4   3   2   1

1 Ответ

0 голосов
/ 09 сентября 2018

Вот функция, которая возвращает перестановку 1,...,n ранга i:

Function Unrank(ByVal n As Long, ByVal rank As Long, Optional lb As Long = 1) As Variant
    Dim Permutation As Variant
    Dim Items As Variant
    ReDim Permutation(lb To lb + n - 1)
    ReDim Items(0 To n - 1)
    Dim i As Long, j As Long, k As Long, q As Long
    Dim fact As Long

    For i = 0 To n - 1
        Items(i) = i + 1
    Next i
    rank = rank - 1
    j = lb
    For i = n - 1 To 1 Step -1
        fact = Application.WorksheetFunction.fact(i)
        q = Int(rank / fact)
        Permutation(j) = Items(q)
        'slide items above q 1 unit to left
        For k = q + 1 To i
            Items(k - 1) = Items(k)
        Next k
        j = j + 1
        rank = rank Mod fact
    Next i
    'place last item:
    Permutation(lb + n - 1) = Items(0)
    Unrank = Permutation
End Function

По умолчанию возвращает результат в виде массива на основе 1. Чтобы сделать его основанным на 0, используйте вызов типа Unrank(5,7,0). В качестве теста:

Sub test()
    'fills A1:A120 with the permutations of 1,2,3,4,5
    Dim i As Long
    For i = 1 To 120
        Cells(i, 1).Value = Join(Unrank(5, i), " ")
    Next i
End Sub

13! слишком велик, чтобы его можно было хранить в переменной Long, поэтому код выдает ошибку без перехвата, когда n=14. Алгоритм, который я использую, зависит от способности выполнять модульную арифметику с соответствующими факториалами, поэтому в VBA нет простого решения. Обратите внимание, что вы можете легко настроить код, чтобы передать ему массив элементов для перестановки, а не всегда переставлять 1-n. Алгоритм уничтожает массив Items, поэтому такая подстройка потребует создания копии переданного массива на основе 0 (чтобы сработала модульная арифметика).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...