LINUX.ORG.RU

Можно ли переписать рекурсивную функцию с двумя листами в итеративную

 


0

1

while, dolist не могу применить, подкиньте идей

(defun m-lst-PHI4 (lst-1 lst-2)
  (if (eq (car lst-1) nil)
      *lst-val-PHI4*
    (progn
    (push (+ (car lst-1) (car lst-2))
	   *lst-val-PHI4*)
    (m-lst-PHI4 (setq lst-1 (cdr lst-1))
		(setq lst-2 (cdr lst-2))))))



Последнее исправление: saufesma (всего исправлений: 1)

(eq (and (car lst-1) (car lst-2)) nil)

Ты специально?
Упрости и заведи локальные переменные, DRY
потом может быть кто-то подскажет

Bad_ptr ★★★★★
()

С Emacs Lisp плохо знаком. Если *lst-val-PHI4* используется только для возврата результата, то лучше действительно использовать локальную переменную.

(defun m-lst-PHI4 (lst-1 lst-2) 
  (progn (while (and (car lst-1) (car lst-2))
                (push (+ (car lst-1) (car lst-2)) *lst-val-PHI4*)
                (setq lst-1 (cdr lst-1))
                (setq lst-2 (cdr lst-2)))
          *lst-val-PHI4*)
Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 4)
Ответ на: комментарий от Siborgium

С Emacs Lisp плохо знаком.

Как же тогда код написал?

Идея простенькая, мне даже в голову не пришла и мозг до сих пор на рекурсии работает.

(defun m-lst-PHI4 (lst-1 lst-2) 
  (progn (while (and (car lst-1) (car lst-2))
                (push (+ (car lst-1) (car lst-2)) *lst-val-PHI4*)
                (setq lst-1 (cdr lst-1))
                (setq lst-2 (cdr lst-2)))
          *lst-val-PHI4*) <= локальная переменная?

saufesma
() автор топика
Ответ на: комментарий от saufesma

Как же тогда код написал?

Не нужно постоянно писать на Emacs Lisp, чтобы уметь написать хелловорлд.

локальная переменная?

Нет, код делает ровно то же, что исходный. С локальной переменной было бы как-то так:

(defun m-lst-PHI4 (lst-1 lst-2)  
  (let (a) 
    (progn (while (and (car lst-1) (car lst-2))
                  (push (+ (car lst-1) (car lst-2)) a)
                  (setq lst-1 (cdr lst-1)) 
                  (setq lst-2 (cdr lst-2))) 
           a) 

Возможно, будет смысл перед циклом установить a в '(), я не помню, как конкретно работает let.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)

Любую рекурсивную программу можно переписать в while или goto программу.

Hint: вместо рекурсивного вызова кладкшь параметры в стэк.

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от invy

Любую рекурсивную программу можно переписать в while или goto программу.

Как насчёт этой?

(defvar lst)
(setq lst '(1 2 3 4 5))
(defvar count)
(setq count 0)


нерабочий код, почему?


(defun pos-in-lst (n lst count)
  (while (not (= n (car lst)))
   (progn
     (setq lst (cdr lst))
   (setq count (+ count 1)))))
  
(pos-in-lst 4 lst count)
count     0

а этот на ура
(defun pos-in-lst (n lst count)
  (if (= n (car lst))
      count
    (pos-in-lst n (setq lst (cdr lst))
		(setq count (+ count 1))))) 

(pos-in-lst 4 lst count)
count     3 как надо
может просветишь где тут я ....

saufesma
() автор топика
Ответ на: комментарий от Siborgium

Не нужно постоянно писать на Emacs Lisp, чтобы уметь написать хелловорлд.

а такой хелловорлд?

(defvar lst)
(setq lst '(1 2 3 4 5))
(defvar count)
(setq count 0)


нерабочий код, почему?


(defun pos-in-lst (n lst count)
  (while (not (= n (car lst)))
   (progn
     (setq lst (cdr lst))
   (setq count (+ count 1)))))
  
(pos-in-lst 4 lst count)
count     0

а этот на ура
(defun pos-in-lst (n lst count)
  (if (= n (car lst))
      count
    (pos-in-lst n (setq lst (cdr lst))
		(setq count (+ count 1))))) 

(pos-in-lst 4 lst count)
count     3 как надо

saufesma
() автор топика
Ответ на: комментарий от saufesma

Я не знаю, почему не работал предыдущий, но предполагаю, что проблема в том, что while возвращает не результат последней итерации, а nil. В новом коде вы возвращаете count явно, поэтому все хорошо.

Я бы переписал как-то так, но замечу, что использовать индексы для адресации по спискам неэффективно. Если найденный count будет использоваться для доступа к элементу, то лучше переписать и возвращать непосредственно список, начинающийся с искомого элемента.

(defun pos-in-lst (n lst)
  (let (count 0)
    (while (not (= n (car lst))) 
           (setq count (+ count 1))) 
    (count)))
Siborgium ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.