Реверс произвольного списка, включая подсписки (XLisp)
Формулировка задачи:
(defun ddin (h n) (cond ((null n) nil) ((> h 0) (ddin (- h 1) (reverse n))) ( (not(atom (car n))) ( cons (ddin (+ h 1) (car n)) (ddin h (cdr n))) ) (t (cons (car n) (ddin h (cdr n)))) ) ) (defun din (n) (ddin 1 n) )
Решение задачи: «Реверс произвольного списка, включая подсписки (XLisp)»
(defun rev-list (lst &aux r) (dolist (i lst r) (push (if (atom i) i (rev-list i)) r))) ==> rev-list (rev-list '(1 2 3 4)) ==> (4 3 2 1) (rev-list '(1 (2 3) 4)) ==> (4 (3 2) 1)
Объяснение кода листинга программы
В коде определённая функция rev-list с двумя аргументами lst и r.
Функция dolist используется для перебора элементов списка lst с помощью i в качестве временной переменной и r в качестве результата.
Если элемент i является атомом, он помещается в начало списка r с помощью функции push.
Если элемент i является списком, вызывается рекурсивно функция rev-list с аргументом i, и результат помещается в начало списка r с помощью функции push.
После завершения перебора списка lst с помощью dolist, результат r будет содержать список, элементы которого расположены в обратном порядке.
Поэтому, если мы применим функцию rev-list к списку (1 2 3 4), мы получим (4 3 2 1).
Если мы применим функцию rev-list к списку (1 (2 3) 4), мы получим (4 (3 2) 1).