Как я могу получить все возможные перестановки списка с языком Common LISP?

Я пытаюсь записать функцию языка Common LISP, которая даст мне все возможные перестановки списка, с помощью каждого элемента только однажды. Например, список' (1 2 3) даст вывод ((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)).

Я уже записал чему-то такие работы, но это неуклюже, это не всегда работает, и я даже действительно не понимаю это. Я не прошу код, просто возможно, для некоторого руководства о том, как думать об этом. Я не знаю много о записи алгоритмов.

Спасибо, Jason

10
задан Vatine 20 January 2010 в 13:27
поделиться

3 ответа

В качестве основного подхода, «все перестановки» следуют этому рекурсивному образцу:

  all permutations of a list L is:
    for each element E in L:
      that element prepended to all permutations of [ L with E removed ]

Если принять, что у вас нет повторяющихся элементов в вашем списке, следует сделать следующее:

(defun all-permutations (list)
  (cond ((null list) nil)
        ((null (cdr list)) (list list))
        (t (loop for element in list
             append (mapcar (lambda (l) (cons element l))
                            (all-permutations (remove element list)))))))
-121--3080543-

Я думаю, что вина заключается в требовании чистоты. Узоры конструкции, включая MVVM, являются инструментом на панели инструментов, а не их конечным элементом. Если имеет смысл порвать с чистотой модели для хорошо обдуманного случая (и это явно выглядит так, как вы рассматривали этот случай), то порвать с моделью.

Если это работает на вас, и вы не верите, что это чрезмерное бремя обслуживания, то я бы сказал, что ничего плохого в том, что вы сделали. Я думаю, что вы явно выполнили бремя доказывания того, что это разумное решение вашей проблемы, несмотря на то, что реализация MVVM может быть чистой.

(Я считаю этот аргумент похожим на аргументы для многопарадигмных языков. Хотя подход Pure OO может быть применен, иногда более уместно делать вещи в более функциональном пути. Хотя может применяться чисто функциональный подход, иногда компромиссы показывают, что методы ОО стоят больше, чем стоит.)

-121--938363-

Пройдите по списку, выбрав каждый элемент по очереди. Этот элемент будет первым элементом вашей текущей перестановки.

Недостатки этот элемент на все перестановки остальных элементов.

3
ответ дан 3 December 2019 в 16:52
поделиться

В качестве основного подхода, "все перестановки" следуют этому рекурсивному шаблону:

  all permutations of a list L is:
    for each element E in L:
      that element prepended to all permutations of [ L with E removed ]

Если мы примем, что в вашем списке нет дублирующих элементов, то сделаем следующее:

(defun all-permutations (list)
  (cond ((null list) nil)
        ((null (cdr list)) (list list))
        (t (loop for element in list
             append (mapcar (lambda (l) (cons element l))
                            (all-permutations (remove element list)))))))
15
ответ дан 3 December 2019 в 16:52
поделиться

Я не уверен, что ваш вопрос о том, что ваш вопрос общим Lisp, или в алгоритме.

Есть похожие проблемы (и решения) для других языков здесь, например, Python . Python часто можно перевести на обычные Lisp практически на линии, так что выберите один и портируйте его? : -)

-2
ответ дан 3 December 2019 в 16:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: