Как переделать код решенной задачи методом рекурсии на реализацию с циклами 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
, иначе выполняется операция умножения.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д