Найти самый глубоко расположенный атом в произвольном списке. - Lisp
Формулировка задачи:
Найти самый глубоко расположенный атом в произвольном списке. Если таких несколько, вывести первый из них.
Прокомментируйте код:
(defun _deepest (x i d)
(cond ((null x) d)
((atom x) (if (> i (car d)) (list i x) d))
(T (_deepest (cdr x) i (_deepest (car x) (+ i 1) d)))))
(defun deepest (x)
(cadr (_deepest x 0 (list 0 nil))))
(deepest '((1) 5 ((8) 9 (4)))) -> 8
(deepest '((1) 5 ((8 3) 9 (4)) 2)) -> 8
(deepest '(1)) -> 1Решение задачи: «Найти самый глубоко расположенный атом в произвольном списке.»
textual
Листинг программы
(defun deepest (w) (cadr (labels ((deep (v n ac) (cond ((null v) ac) ((atom v) (if (> n (car ac)) `(,n ,v) ac)) ((deep (cdr v) n (deep (car v) (1+ n) ac)))))) (deep w 0 `(0 nil))))) > (deepest '((1) 5 ((8) 9 (4)))) 8
Объяснение кода листинга программы
В данном коде определённая функция deepest, которая принимает один аргумент w. Этот аргумент должен быть списком. Внутри функции происходит рекурсивный обход списка до тех пор, пока не будет найден самый глубоко расположенный атом.
В первой строке кода функция cadr используется для получения второго элемента списка. Далее, с помощью labels определяется внутренняя функция deep, которая принимает четыре аргумента v, n, ac и cdr v.
Внутренняя функция deep проверяет следующие условия:
- Если
vравноnil, то возвращаетсяac. - Если
vявляется атомом, то проверяется следующее условие: еслиnбольшеcar ac, то возвращается новая списковая структура, содержащаяnиv. В противном случае возвращаетсяac. - Если
vне являетсяnilиcdr vне равноnil, то рекурсивно вызывается функцияdeepс аргументамиcdr v,n+1иdeep (car v). В последней строке кода функцияdeepestвызывается с аргументомw, равным списку((1) 5 ((8) 9 (4)). При этом, для обхода списка используется рекурсивный вызов функцииdeepс аргументамиw,0и(0 nil). Таким образом, в результате выполнения кода будет выведено число8, так как это самый глубоко расположенный атом в списке((1) 5 ((8) 9 (4))).