Найти все числа в списке и объединить их в выходной список - Lisp
Формулировка задачи:
Доброго всем вечера.
Определить функцию collect-numbers(s-exp), которая возвращает
список всех чисел s-выражений. S-выражение может быть атомом
или списком s-выражений. Например:
Вот вариант, который вышел у меня. Первая функция объединяет все уровни списка в один, а вторая должна его обрабатывать по заданию. Но что-то не могу понять, как их заставить работать совместно, т.е. чтобы функция fff работала с переменной а из памяти.
Заранее спасибо
Листинг программы
- > (collect-numbers 1)
- (1)
- > (collect-numbers ‘a)
- NIL
- > (collect-numbers ‘(1 (b (2 c) ((3)))))
- (1 2 3)
Листинг программы
- (defun v (x &OPTIONAL (r nil))
- (cond
- ((null x) (setq a r))
- ((atom x) (setq a (cons x r)))
- (t (setq a (v (car x) (v (cdr x) r))))
- )
- )
- (defun fff (a &OPTIONAL (b nil))
- (if (integerp (car a)) (cons (car a) b)) ;если голова а - число, включить его в б
- (if (cdr a nil) (print b) (fff (cdr a) b))) ;если хвост а пустой, напечатать б, если нет, то вызвать fff от хвоста а.
Решение задачи: «Найти все числа в списке и объединить их в выходной список»
textual
Листинг программы
- (defun task (lst &optional (r nil))
- (cond ((null lst) (reverse r))
- ((numberp lst) (list lst))
- ((atom lst) nil)
- ((numberp (car lst)) (task (cdr lst) (cons (car lst) r)))
- ((listp (car lst)) (task (cdr lst) (append (reverse (task (car lst))) r)))
- (t (task (cdr lst) r))))
- ==> task
- (task 'a)
- ==> NIL
- (task '(1 (b (2 c) ((3)))))
- ==> (1 2 3)
Объяснение кода листинга программы
В коде определён функционал для решения поставленной задачи.
- Если входной список (lst) пустой, то возвращается перевёрнутый список (reverse r), если он не пустой.
- Если элемент списка (lst) является числом, то возвращается список, содержащий этот элемент.
- Если элемент списка (lst) является атомом (не числом и не списком), то возвращается NIL.
- Если первый элемент списка (lst) является числом, то рекурсивно вызывается функция task для оставшейся части списка (cdr lst) и добавляется в начало результат вызова функции task для первого элемента (cons (car lst) r).
- Если первый элемент списка (lst) является списком, то рекурсивно вызывается функция task для оставшейся части списка (cdr lst) и возвращается результат вызова функции task для первого элемента (append (reverse (task (car lst))) r).
- Если первый элемент списка (lst) не является числом или списком, то рекурсивно вызывается функция task для оставшейся части списка (cdr lst) и возвращается список r. Пример использования функции: (task 'a) -> NIL (task '(1 (b (2 c) ((3))))) -> (1 2 3)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д