Задача с использованием рекурсии и циклов - Lisp
Формулировка задачи:
необходимо реализовать задачу 2 вариантами: 1.с помощью рекурсии 2.с помощью циклов.
Определить функцию, осуществляющую несколько замен х на у в исходном списке по ассоциативному списку: ((x1.y1)(x2.y2)(x3.y3).....)
Решение задачи: «Задача с использованием рекурсии и циклов»
textual
Листинг программы
;; рекурсивная версия (defun to-repl-r (x asso-list) (cond ((null asso-list) x) ((eq x (caar asso-list)) (cdar asso-list)) (t (to-repl-r x (cdr asso-list))))) ==> TO-REPL-R (to-repl-r 'x '((z . 1) (x . 2) (y . 3))) ==> 2 (to-repl-r 'r '((z . 1) (x . 2) (y . 3))) ==> R ;; Циклическая версия (defun to-repl-l (x asso-list) (dolist (a asso-list x) (when (eq (car a) x) (return (cdr a))))) ==> TO-REPL-L (to-repl-l 'r '((z . 1) (x . 2) (y . 3))) ==> R (to-repl-l 'y '((z . 1) (x . 2) (y . 3))) ==> 3
Объяснение кода листинга программы
В коде представлено два варианта реализации замены символа в ассоциативном списке: рекурсивная и циклическая.
- Рекурсивная версия:
- (defun to-repl-r (x asso-list)
(cond ((null asso-list) x)
((eq x (caar asso-list)) (cdar asso-list))
(t (to-repl-r x (cdr asso-list)))))
В этом варианте реализована рекурсивная функция
to-repl-r, которая принимает два аргумента:xиasso-list.x- символ, который необходимо заменить, аasso-list- ассоциативный список, в котором производится замена. Функция работает следующим образом:
- (defun to-repl-r (x asso-list)
(cond ((null asso-list) x)
((eq x (caar asso-list)) (cdar asso-list))
(t (to-repl-r x (cdr asso-list)))))
В этом варианте реализована рекурсивная функция
- Если
asso-listравенnil, то возвращаетсяx, так как замена не может быть выполнена. - Если
xравенcarизasso-list, то возвращаетсяcdarизasso-list, так как замена выполнена. - Если условие не выполняется, то рекурсивно вызывается
to-repl-rс аргументамиxиcdrизasso-list. - Циклическая версия:
- (defun to-repl-l (x asso-list)
(dolist (a asso-list x)
(when (eq (car a) x) (return (cdr a)))))
В этом варианте реализована циклическая функция
to-repl-l, которая также принимает два аргумента:xиasso-list. Функция работает следующим образом:
- (defun to-repl-l (x asso-list)
(dolist (a asso-list x)
(when (eq (car a) x) (return (cdr a)))))
В этом варианте реализована циклическая функция
- С помощью цикла
dolistперебираются элементыasso-list. - Если
carтекущего элемента равенx, то возвращаетсяcdrтекущего элемента, так как замена выполнена. Пример использования функций:- (to-repl-r 'x '((z . 1) (x . 2) (y . 3))) -> 2
- (to-repl-r 'r '((z . 1) (x . 2) (y . 3))) -> R
- (to-repl-l 'y '((z . 1) (x . 2) (y . 3))) -> 3