На этом шаге мы рассмотрим примеры использования рекурсии по значению и по аргументам.
В этом разделе мы рассмотрим лишь несколько примеров.
(DEFUN REMOVE (LAMBDA (ATM LST)
(COND ( (NULL LST) NIL)
( (EQ ATM (CAR LST))
; Рекурсия по значению
(REMOVE ATM (CDR LST)) )
( T ; Рекурсия по аргументу
(CONS (CAR LST)
(REMOVE ATM (CDR LST))) )
)
))
Список LST сокращается путем удаления всех идентичных ATM в смысле EQ элементов (вторая ветвь) и копирования в результирующий список (CONS) остальных элементов (третья ветвь) до тех пор, пока условие окончания (первая ветвь) не станет истинным. Результат формируется в процессе возврата.
Замечание. Функцию REMOVE можно определить с использованием предиката
EQUAL вместо EQ. С помощью такой функции можно удалять элементы, являющиеся списками!
(DEFUN MEMBERN (LAMBDA (X LST)
(COND ( (NULL LST) NIL)
( T (OR (COND ( (ATOM (CAR LST))
(MEMBERN X (CDR LST)) )
( T (OR (EQUAL X (CAR LST))
(MEMBERN X (CAR LST))) )
)
(MEMBERN X (CDR LST))
)
)
)
))
(DEFUN SUMMA (LAMBDA (X LST) ; Подсчитать сумму мест, на которых в списке LST ; встречается элемент X (COND ( (NULL LST) 0 ) ( (EQ X (FOOT LST)) (+ (SUMMA X (HEAD LST)) (LENGTH LST)) ) ( T (SUMMA X (HEAD LST)) ) ) )) ; --------------------- (DEFUN FOOT (LAMBDA (LST) (CAR (REVERSE LST)) )) ; --------------------- (DEFUN HEAD (LAMBDA (LST) (REVERSE (CDR (REVERSE LST))) ))
(DEFUN REVERSE1 (LAMBDA (LST) ; "Обращение" списка LST на первом уровне ( (NULL LST) NIL) ( APPEND1 (REVERSE1 (CDR LST)) (CAR LST) ) )) ; -------------------------- (DEFUN APPEND1 (LAMBDA (LST X) ( (NULL LST) (CONS X NIL) ) ; Создание одноэлементного списка ( CONS (CAR LST) (APPEND1 (CDR LST) X) ) ))
На следующем шаге мы рассмотрим параллельную рекурсию.