Разобраться в ошибке - Lisp (229492)
Формулировка задачи:
(defun f(x)(if (> x 0) T nil));;предикат выводящий Т если число больше нуля,в противном случае Nil (defun pos (x L);;функция находящая позицию(индекс) элемента в списке (if (eq (car L) x) 0 (+ 1 (pos x (cdr L))))) (defun spisok_pozich(L f pos);;главная функция ( cond ((null l) nil) (t ((f(car l) T) (cons (pos(carl L)) (spisok_pozich((cdr L) f pos)))) )))
Решение задачи: «Разобраться в ошибке»
(defun spisok_pozich(L f &optional (n 0)) (cond ((null l) nil) ((funcall f (car l)) (cons n (spisok_pozich (cdr L) f (+ 1 n)))) (t (spisok_pozich (cdr L) f (+ 1 n))))) ==> spisok_pozich (spisok_pozich '(1 -2 9 -5 2) 'f) ==> (0 2 4)
Объяснение кода листинга программы
В данном коде определенная функция spisok_pozich
принимает три аргумента: список L
, функцию f
и опциональный аргумент n
со значением по умолчанию 0.
Если список L
пуст, то возвращается nil
.
Если функция f
применительно к первому элементу списка L
возвращает не nil
, то возвращается новая функция, которая вызывается с аргументами (cdr L)
(то есть, список без первого элемента), f
и n + 1
.
Если первый элемент списка L
не удовлетворяет условию выше, то вызывается рекурсивно spisok_pozich
с аргументами (cdr L)
(то есть, список без первого элемента), f
и n + 1
.
Таким образом, если применить spisok_pozich
к списку (1 -2 9 -5 2)
и функции f
, которая возвращает 2 при делении на 2 и 0 в противном случае, то вернется список (0 2 4)
. Это означает, что функция f
вернула 2 при делении на 2 первого элемента списка (1 -2 9 -5 2)
, после чего была вызвана рекурсивно с аргументами (cdr L)
(то есть, список без первого элемента) и n + 1
(то есть, 2 + 1
или 3
). Поскольку второй элемент списка также удовлетворяет условию, то рекурсия продолжилась, и в итоге был возвращен список (0 2 4)
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д