Учитывая список значений, например vec![0, 0, 1, 2]
, я хотел бы создать итератор, генерирующий все его уникальные перестановки. То есть
[0, 0, 1, 2]
[0, 0, 2, 1]
[0, 1, 0, 2]
[0, 1, 2, 0]
[0, 2, 0, 1]
[0, 2, 1, 0]
[1, 0, 0, 2]
[1, 0, 2, 0]
[1, 2, 0, 0]
[2, 0, 0, 1]
[2, 0, 1, 0]
[2, 1, 0, 0]
(обратите внимание, что существует 12 различных перестановок, в то время как если бы у нас было 4 различных элементов, было бы 24 различных перестановки).
Там Это уже способ генерировать перестановки (а также другие итераторы, такие как комбинации или комбинации без замен) с использованием пакета itertools , но для перестановок нет способа ограничить перестановки только теми, которые являются уникальными.
Существует довольно эффективный алгоритм генерации перестановок, в общем известный как Алгоритм кучи , однако он не учитывает равенство / двойственность значений.
Эта проблема не слишком сложно реализовать в языках с генераторами, , таких как Python, но я чувствую, что это более сложно в Rust (по крайней мере, по сравнению с решением выше), так как для этого потребуется использование итераторов ( который должен поддерживать внутреннее состояние), или используя генераторы (которые в настоящее время нестабильны ).