Вычислить сумму числовых элементов списка, учитывая элементы подсписков - Lisp
Формулировка задачи:
Доброго времени суток!
Задача состоит в следующем: Вычислить сумму числовых элементов списка, учитывая элементы подсписков.
Вот мой код.
В результате вызова функции выдает следующее:
(defun soe (lst) (cond ((null lst) 0) (( and (atom lst) (numberp lst)) lst) (t (+ (soe (car lst)) (soe (cdr lst))) )))
> (soe '( 2 3 f ( 2 g ) 2)) Error: Cannot take CAR of F.
Решение задачи: «Вычислить сумму числовых элементов списка, учитывая элементы подсписков»
textual
Листинг программы
;; просто рекурсия (defun sum-num (lst) (cond ((null lst) 0) ((listp (car lst)) (+ (sum-num (car lst)) (sum-num (cdr lst)))) ((numberp (car lst)) (+ (car lst) (sum-num (cdr lst)))) (t (sum-num (cdr lst))))) ==> SUM-NUM (sum-num '(1 2 3 a b (((c))) (((7 8))))) ==> 21 ;; итерации + рекурсия (defun sum-num (lst) (let ((s 0)) (dolist (a lst s) (cond ((listp a) (setf s (+ s (sum-num a)))) ((numberp a) (setf s (+ s a))))))) ==> SUM-NUM (sum-num '(1 2 3 a b (((c))) (((7 8))))) ==> 21 ;; функционалы + рекурсия (defun sum-num (lst) (apply '+ (mapcar (lambda (x) (cond ((listp x) (sum-num x)) ((numberp x) x) (t 0))) lst))) ==> SUM-NUM (sum-num '(1 2 3 a b (((c))) (((7 8))))) ==> 21
Объяснение кода листинга программы
В коде представлено три варианта вычисления суммы числовых элементов списка, учитывая элементы подсписков.
- Просто рекурсивный вариант:
- Функция
sum-numпринимает списокlstв качестве входного параметра. - Если
lstявляетсяnil, то возвращается 0. - Если
car lstявляется списком, то рекурсивно вызываетсяsum-numдляcar lstиcdr lst. - Если
car lstявляется числом, тоcar lstдобавляется к результату рекурсивного вызоваsum-numдляcdr lst. - В остальных случаях, результат рекурсивного вызова
sum-numдляcdr lstвозвращается.
- Функция
- Вариант с использованием итераций и рекурсии:
- Функция
sum-numпринимает списокlstв качестве входного параметра. - Создается переменная
sсо значением 0. - Используется
dolistдля итерации по элементамlst. - Если элемент
aявляется списком, то рекурсивно вызываетсяsum-numдляaи результат добавляется кs. - Если элемент
aявляется числом, тоaдобавляется кs. - В остальных случаях,
sвозвращается.
- Функция
- Вариант с использованием функционалов и рекурсии:
- Функция
sum-numпринимает списокlstв качестве входного параметра. - Используется
applyдля применения функции+к результатамmapcar. mapcarприменяется к элементамlstс использованием лямбда-функции, которая рекурсивно вызываетsum-numдля списков и возвращает числовые значения для чисел.- Если элемент
xявляется списком, то рекурсивно вызываетсяsum-numдляx. - Если элемент
xявляется числом, тоxвозвращается. - В остальных случаях, возвращается 0.
- Функция