Как переделать код решенной задачи методом рекурсии на реализацию с циклами Do, и Loop - Lisp
Формулировка задачи:
Дана последовательность чисел а1 ... аn. Если в результате замены отрицательных членов последовательности их квадратами, члены будут образовывать последовательность которая уменьшается, то получить сумму членов исходной последовательности, в противном случае получить их произведение.
(DEFUN UBV(L &OPTIONAL (B NIL)) (COND ((NULL L) (SETQ B NIL)) ((NULL(CADR L)) B) ((>(CAR L)(CADR L)) (UBV(CDR L)(SETQ B T))) (T NIL) )) (DEFUN SUM (L &OPTIONAL (S 0)) (COND ((NULL L) S) ((NOT (NULL L)) (SUM (CDR L) (+ S (CAR L)))) )) (DEFUN MUL (L &OPTIONAL (M 1)) (COND ((NULL L) M) ((NOT (NULL L)) (MUL (CDR L) (* M (CAR L)))) )) (DEFUN PR1(L &OPTIONAL (L2 NIL)) (COND ((AND (NULL L)(NULL L2)) NIL) ((AND (NOT(NULL L))(MINUSP (CAR L))) (PR1 (CDR L) (APPEND L2 (LIST(* (CAR L)(CAR L)))))) ((AND (NOT (NULL L))(PLUSP (CAR L))) (PR1 (CDR L) (APPEND L2 (LIST (CAR L))))) ((AND (NULL L) (NOT (NULL L2)) (UBV L2)) (SUM L2)) ((AND (NULL L) (NOT (NULL L2)) (NOT (UBV L2))) (MUL L2)) ))
Решение задачи: «Как переделать код решенной задачи методом рекурсии на реализацию с циклами Do, и Loop»
textual
Листинг программы
;; Функциональное (defun task (lst) (let ((lst-n (mapcar (lambda (x) (if (minusp x) (* x x) x)) lst))) (if (apply '> lst-n) (apply '+ lst) (apply '* lst)))) ==> TASK (task '(100 -8 50 -7)) ==> 135 (task '(1 2 3 4 -1 -2 -3)) ==> -144 ;; итерационное с DO (defun task (lst) (let ((n (length lst)) (r nil)) (do ((i 0 (+ i 1))) ((= i n) (if (apply '< r) (apply '+ lst) (apply '* lst))) (let ((c (nth i lst))) (push (if (minusp c) (* c c) c) r))))) ==> TASK (task '(1 2 3 4 -1 -2 -3)) ==> -144 (task '(100 -8 50 -7)) ==> 135 ;; Итерационное с LOOP (defun task (lst) (let ((n (length lst)) (r nil) (i 0) (c 0)) (loop (when (= i n) (return (if (apply '< r) (apply '+ lst) (apply '* lst)))) (setq c (nth i lst)) (push (if (minusp c) (* c c) c) r) (setq i (+ i 1))))) ==> TASK (task '(100 -8 50 -7)) ==> 135 (task '(1 2 3 4 -1 -2 -3)) ==> -144
Объяснение кода листинга программы
Код выполняет следующие действия:
- Функция
task
принимает списокlst
в качестве входного параметра. - В функциональном варианте кода, список
lst
преобразуется в списокlst-n
, где каждый элементx
заменяется на(* x x)
еслиx
отрицательный, иначе наx
. - Затем проверяется, больше ли
lst-n
чем текущий элемент спискаlst
. Если это так, то выполняется операция сложения для всех элементов спискаlst
, иначе выполняется операция умножения. - В итерационном варианте кода с использованием
DO
, создается переменнаяr
, которая инициализируется как пустой список. - Затем выполняется цикл
DO
, который проходит через каждый элемент спискаlst
. - Внутри цикла, элемент
c
сохраняется в переменнойc
. - Если
c
отрицательный, то он заменяется на(* c c)
, иначе наc
. - Затем
c
добавляется в списокr
. - После завершения цикла, проверяется, равен ли размер списка
r
размеру спискаlst
. Если это так, то выполняется операция сложения для всех элементов спискаlst
, иначе выполняется операция умножения. - В итерационном варианте кода с использованием
LOOP
, создаются переменныеn
,r
,i
иc
, которые инициализируются как пустой список и 0 соответственно. - Затем выполняется цикл
LOOP
, который проходит через каждый элемент спискаlst
. - Внутри цикла, проверяется, равен ли
i
размеру спискаlst
. Если это так, то цикл завершается и возвращается результат операцииr
. - После проверки условия цикла, элемент
c
сохраняется в переменнойc
. - Затем
c
добавляется в списокr
. - После этого,
i
увеличивается на 1. - Если цикл завершается, то выполняется операция сложения для всех элементов списка
lst
, иначе выполняется операция умножения.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д