Одиночные кавычки в функции Laravel / PHP str_replace для отображения смайликов

Мне всегда было легче понять алгоритм на более высоком уровне, прежде чем погрузиться в реализацию и попытаться понять, что там происходит. Итак, возникает вопрос: каковы перестановки списка и как вы их найдете?

Перестановки одного списка элементов, по-видимому, являются только самим списком.

Перестановки (a b) являются множеством [(a b) (b a)].

Перестановки (a b c) - это множество

[(a b c) (a c b) (b c a) (b a c) (c a b) (c b a)]

. В общем случае существуют n! перестановки списка длины n - у нас есть n вариантов для первого элемента, и как только мы выбрали это, (n-1) выбор для второго элемента (n-2) для третьего элемента и так далее. Это уменьшение степеней свободы по мере того, как мы фиксируем все больше и больше первых элементов списка, очень наводящий на размышления: возможно, мы можем представить нахождение перестановок списка длины n в терминах перестановок списка длины (n - 1) и так далее, пока мы не достигнем перестановок одноэлементного списка.

Оказывается, что перестановки списка точно представляют собой набор [элемент, добавленный к перестановкам списка \ element, для каждого элемента в списке].

Глядя на случай (a b c), подтверждает, что это правда - мы имеем a, предшествующие (b c) и (c b), которые являются перестановками (b c), b, предшествующими (a c) и (c a) и т. д. Эта операция добавления элемента в подсписку может быть определена как

(define (prepend j)
  (cons element j))

, и тогда выполнение этой операции для всех перестановок подписок будет (map prepend (permute sublist)). Теперь определение новой функции preend для каждого элемента может быть чрезмерным - тем более, что все они имеют одинаковую форму. Поэтому лучше использовать только лямбду, которая фиксирует значение рассматриваемого элемента. Тогда желаемая операция будет (map (lambda (j) (cons element j)) (permute sublist)). Теперь мы хотим применить эту операцию к каждому элементу списка, а способ сделать это - использовать другую карту, дающую:

(map (lambda (element)
       (lambda (j) (cons element j) (permute sublist)))
     list)

Теперь это выглядит хорошо, но есть проблема: каждый этап рекурсии принимает отдельные элементы и превращает их в список. Это хорошо для списков длины 1, но для более длинных списков он повторяется для каждого рекурсивного вызова, и мы получаем очень глубоко вложенные списки. Мы действительно хотим сделать все эти списки на одной и той же основе, и это точно то, о чем заботится (apply append ...). И это почти вся эта линия. Единственное, чего не хватает, - это то, как создается подсписчик в первую очередь. Но это также легко - мы просто используем remove, так что sublist = (remove element list). Соединяя все, и у нас есть

(apply append (map (lambda (i)
                      (lambda (j) (cons i j))
                      (permute (remove i lst)))
                    lst))

. Основной случай заботится о случае длины = 1, и все остальные могут быть найдены там

0
задан Edwin Krause 26 February 2015 в 10:24
поделиться