Деревья и графы - Lisp
Формулировка задачи:
Решение задачи: «Деревья и графы»
CL-USER 1 > (defun forsome (L p) (COND ((NULL L) NIL) ((FUNCALL p (CAR L)) T) (T (forsome (CDR L) p)))) FORSOME CL-USER 2 > (defun del-node (tree v) (cond ((forsome tree #'(lambda (x) (eq (car x) v))) (let ((qq (cdar (remove-if-not #'(lambda (x) (eq v (car x))) tree))) (vv (remove-if #'(lambda (x) (eq v (car x))) tree))) (mapcar #'(lambda (x) (if (member v x) (append (remove v x) qq) x)) vv))) (t (remove-if #'(lambda (y) (null (cdr y))) (mapcar #'(lambda (x) (remove v x)) tree))))) DEL-NODE CL-USER 3 > (setq *t* '((r a b) (a c d e) (b k l m) (d f g) (k n o) (l p))) ((R A B) (A C D E) (B K L M) (D F G) (K N O) (L P)) CL-USER 4 > (del-node *t* 'd) ((R A B) (A C E F G) (B K L M) (K N O) (L P))
Объяснение кода листинга программы
В первом куске кода определяют функцию forsome. Она принимает два аргумента: список L и предикат p. Если L — это nil, то возвращается nil. Иначе, возвращается T, когда предикат p применяется к первому элементу L. В противном случае, рекурсивно вызывается forsome для оставшейся части списка L и предиката p.
Второй кусок кода определяет функцию del-node. Она принимает два аргумента: дерево tree и значение v. Если v присутствует в корневом узле дерева, то рекурсивно вызывается del-node для оставшейся части дерева без корневого узла. В противном случае, рекурсивно вызывается del-node для каждого поддерева, которое не содержит v в корневом узле.
В третьем куске кода устанавливается переменная *t* в список ((r a b) (a c d e) (b k l m) (d f g) (k n o) (l p)).
В четвёртом куске кода вызывается функция del-node с аргументами *t* и d. В результате выполнения функции, d удаляется из списка *t*, и возвращается новый список без d.