Необычный вывод позиции найденного элемента в ЛЮБОМ списке - Lisp
Формулировка задачи:
Помогите пожалуйста!!!!
Если не сложно - с комментариями! Lisp мне не поддается...(((
ЗАДАЧА:
В нелинейном списке найти заданный элемент (м.б., не атом). Результат выдать в виде линейного списка (отдельный список для каждого вхождения), каждый элемент которого является индексом очередного сегмента поиска. Если элемент не найден, выдать 0.
Решение задачи: «Необычный вывод позиции найденного элемента в ЛЮБОМ списке»
textual
Листинг программы
(defun task (item lst &optional (p 0) (r nil) (res nil)) (cond ((null lst) res) ((equal (car lst) item) (task item (cdr lst) (+ p 1) r (append res (list (reverse (cons p r)))))) ((listp (car lst)) (let ((tmp (task item (car lst) 0 (cons p r) nil))) (task item (cdr lst) (+ p 1) r (append res tmp)))) (t (task item (cdr lst) (+ p 1) r res)))) ==> task (task '(8 5) '(8 5 (8 5) 1 1 (1 (8 5)) 1 (1 ((8 5) 1)))) ==> ((2) (5 1) (7 1 0)) (task 1 '(8 5 (8 5) 1 1 (1 (8 5)) 1 (1 ((8 5) 1)))) ==> ((3) (4) (5 0) (6) (7 0) (7 1 1))
Объяснение кода листинга программы
В этом коде определённая функция task, которая принимает три аргумента: item, lst и два необязательных аргумента p и r. Если p не указан, он по умолчанию равен 0. Если r не указан, он по умолчанию равен nil.
Функция task выполняет следующие действия:
- Если
lstравноnil, функция возвращаетres. - Если
car lstравноitem, функция вызывает саму себя, передаваяitem,cdr lst,p + 1иrв качестве аргументов. Она также добавляетpв конецres. - Если
car lstявляется списком, функция вызывает саму себя, передаваяitem,cdr lst,p + 1иrв качестве аргументов. Она также добавляет результат вызова функции, в которомpувеличивается на 1, в конецres. - Если
car lstне является списком, функция вызывает саму себя, передаваяitem,cdr lst,p + 1иrв качестве аргументов. В данном примере функцияtaskвызывается с аргументами'(8 5)', '(8 5 (8 5) 1 1 (1 (8 5)) 1 (1 ((8 5) 1))',1иnilсоответственно. Функция ищет все вхождения'8 5'в списке и возвращает список позиций, где'8 5'встречается, в порядке их появления. В этом примере результат будет(2) (5 1) (7 1 0). Если бы мы использовалиtaskс аргументом'1', мы бы получили(3) (4) (5 0) (6) (7 0) (7 1 1).