Обмен элементов в списке Common Lisp - PullRequest
12 голосов
/ 17 октября 2010

Существует ли функция Common Lisp, которая будет менять два элемента в списке с учетом их индексов и возвращать измененный список?

Ответы [ 2 ]

17 голосов
/ 17 октября 2010

Вы можете использовать rotatef:

(rotatef (nth i lst) (nth j lst))

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

(rotatef (aref arr i) (aref arr j))
4 голосов
/ 17 октября 2010

Я бы не использовал индексирование в списке дважды, используя nthcdr, чтобы получить cdr ячейки cons, содержащей первый элемент, который вы хотите поменять, а затем используйте elt, чтобы вывести оставшийся элемент из подсписка.Это означает, что вам нужно только один раз индексировать, начиная с заголовка списка.

 (let ((list-tail (nthcdr i list)))
    (rotatef (car list-tail)
             (elt list-tail (- j i)))
    list)

По крайней мере, с моей точки зрения, это достаточно утомительно, чтобы оправдать функцию.

...