Вещь перестановки [дубликат]

avatar
matt.whitby
1 июля 2021 в 19:12
41
1
-3

Как можно написать функцию (на Python), которая:

Если мы возьмем все перестановки для A, B и C: ABC, ACB, BAC, BCA, CAB, CBA

Функция берет индекс и возвращает перестановку для этого индекса.

Например. F("ABC", 4) вернет "BCA"

Он должен выполняться за разумное время для очень больших наборов перестановок.

Источник
Samwise
1 июля 2021 в 19:13
0

Должен ли он работать в разумные сроки и для очень больших индексов?

Giovanni Rescia
1 июля 2021 в 19:15
2

Здравствуйте и добро пожаловать в coderhelper! Не могли бы вы поделиться тем, что вы пробовали до сих пор?

Captain Trojan
1 июля 2021 в 19:16
0

Каков порядок перестановок? Всегда ли оно лексикографично?

not_speshal
1 июля 2021 в 19:17
0

См. itertools.permutations в качестве отправной точки, но, вероятно, не для "очень больших наборов перестановок".

John Coleman
1 июля 2021 в 19:22
0

В книге Стэнтона и Уайта «Конструктивная комбинаторика» содержится много таких алгоритмов. Он дает псевдокод, похожий на Pascal, который достаточно легко перевести на Python. Как общий ресурс для всех таких вопросов, я настоятельно рекомендую его.

Ответы (1)

avatar
Green Cloak Guy
1 июля 2021 в 19:18
0

Вы можете анализировать/фильтровать результаты itertools.permutations(), потому что генераторы не могут быть проиндексированы напрямую. Такая функция сделает это:

from itertools import permutations

def nth_permutation(items, n):
    i = 0
    perms = permutations(items)
    try:
        next_perm = next(perms)
        while i < n:
           next_perm = next(perms)
           i += 1
    except StopIteration:
        # implement error behavior here, if n > number of permutations. 
        # For now we just return the default value, None
        # you might instead try throwing an IndexError
        return None
    return next_perm

(обратите внимание, что перестановка с индексом 4 является "CAB" - "BCA" является индексом 3)

John Coleman
1 июля 2021 в 19:21
1

«Вам нужно будет проанализировать/отфильтровать результаты itertools.permutations()» — зачем так говорить? Довольно просто найти перестановку # 345 678 911 алфавита, фактически не создавая более одной перестановки.

kaya3
1 июля 2021 в 19:21
2

Вам не нужно генерировать все перестановки до n-й; существует алгоритм для генерации n-й перестановки напрямую с использованием факториалов, которые можно найти в связанном дубликате.