Использование рекурсии - Lisp

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

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

Здравствуйте, помогите, пожалуйста! Нужно описать функцию, используя функции car и cdr, которая определяла бы положение атома в списке (возвращала бы порядковый номер атома в списке), учитывая все атомы подсписков. Например, результатом применения функции к аргументам ’x ’((a (3 b)) a (c x d)) (5 (a 8))) должен быть 5 – нумерация начинается с 0.

Решение задачи: «Использование рекурсии»

textual
Листинг программы
(defun flat (lst)
  (cond ((null lst) nil)
        ((atom (car lst)) (cons (car lst) (flat (cdr lst))))
        (t (append (flat (car lst)) (flat (cdr lst))))))
 
==> FLAT
 
(defun pos-of-atom (lst a p)
  (cond ((null lst) nil)
        ((eq (car lst) a) p)
        (t (pos-of-atom (cdr lst) a (+ p 1))))) 
 
==> POS-OF-ATOM
 
(defun task (lst a)
  (pos-of-atom (flat lst) a 0))
 
==> TASK
 
(task '(((a (3 b)) a (c x d)) (5 (a 8))) 'x)
 
==> 5

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

В коде представлена функция flat, которая принимает в качестве аргумента список lst и возвращает список, содержащий только один уровень вложенности. Рекурсивный базовый случай составляет NULL-значение, которое передаётся в качестве значения для всех дочерних элементов. Функция pos-of-atom принимает три аргумента: список lst, атом a и индекс p. Если lst — NULL, то возвращается NULL. Если car lst равен a, то возвращается p. В противном случае рекурсивно вызывается функция pos-of-atom для cdr lst, при этом p увеличивается на 1. Функция task принимает два аргумента: список lst и атом a. Она вызывает функцию pos-of-atom с аргументами flat lst и a, передаёт результат в функцию flat, и возвращает результат. Вызывается функция task с аргументами '(((a (3 b)) a (c x d)) (5 (a 8))) и 'x'. Функция flat преобразует входной список в список с одним уровнем вложенности, затем функция pos-of-atom вызывается с аргументами '((a (3 b)) a (c x d))' и 'x', и возвращает 5. Итоговый результат: 5.

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

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