Найти все числа в списке и объединить их в выходной список - Lisp

Узнай цену своей работы

Формулировка задачи:

Доброго всем вечера. Определить функцию collect-numbers(s-exp), которая возвращает список всех чисел s-выражений. S-выражение может быть атомом или списком s-выражений. Например:
> (collect-numbers 1)
(1)
> (collect-numbers ‘a)
NIL
> (collect-numbers ‘(1 (b (2 c) ((3)))))
(1 2 3)
Вот вариант, который вышел у меня. Первая функция объединяет все уровни списка в один, а вторая должна его обрабатывать по заданию. Но что-то не могу понять, как их заставить работать совместно, т.е. чтобы функция fff работала с переменной а из памяти.
(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)

Объяснение кода листинга программы

В коде определён функционал для решения поставленной задачи.

  1. Если входной список (lst) пустой, то возвращается перевёрнутый список (reverse r), если он не пустой.
  2. Если элемент списка (lst) является числом, то возвращается список, содержащий этот элемент.
  3. Если элемент списка (lst) является атомом (не числом и не списком), то возвращается NIL.
  4. Если первый элемент списка (lst) является числом, то рекурсивно вызывается функция task для оставшейся части списка (cdr lst) и добавляется в начало результат вызова функции task для первого элемента (cons (car lst) r).
  5. Если первый элемент списка (lst) является списком, то рекурсивно вызывается функция task для оставшейся части списка (cdr lst) и возвращается результат вызова функции task для первого элемента (append (reverse (task (car lst))) r).
  6. Если первый элемент списка (lst) не является числом или списком, то рекурсивно вызывается функция task для оставшейся части списка (cdr lst) и возвращается список r. Пример использования функции: (task 'a) -> NIL (task '(1 (b (2 c) ((3))))) -> (1 2 3)

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.167 из 5
Похожие ответы