Algorithm 如何将此递归解决方案转换为迭代解决方案?

Algorithm 如何将此递归解决方案转换为迭代解决方案?,algorithm,lisp,elisp,Algorithm,Lisp,Elisp,我在Lisp中有以下递归函数 (defun f (item tree) (when tree (if (equal item (car tree)) tree (if (and (listp (car tree)) (equal item (caar tree))) (car tree) (if (cdr tree) (f item (cdr tree))))))) 此函数接收一棵树和一个要在其直接叶子中查找的项

我在Lisp中有以下递归函数

(defun f (item tree)
  (when tree
    (if (equal item (car tree)) tree
      (if (and (listp (car tree))
           (equal item (caar tree)))
      (car tree)
    (if (cdr tree)
        (f item (cdr tree)))))))
此函数接收一棵树和一个要在其直接叶子中查找的项。如果项目是任何子列表的汽车,那么它将返回该子列表。就是

  • (f'c'(a b c))=>(c)
  • (f'b'(abc))=>(bc)
  • (f'a'((a2)bc))=>(a2)
我最近被告知(Emacs Lisp)不进行尾部递归优化,所以我被建议将其转换为
while
循环。我所有的Lisp训练都是为了避免这样的循环。(我坚持认为它们没有功能性,但这有点迂腐。)我尝试了以下更符合风格的方式:

(defun f (item tree)
  (let ((p tree))
    (while p
      (cond
       ((equal item (car p)) p)
       ((and (listp (car p))
             (equal item (caar p)))
        (car tree))
       (t (f item (cdr p))))
      (setq p (cdr p)))))
为简洁/清晰起见,我缩短了函数名,但请看一下您是否是emacs的超级用户。

您的“迭代”解决方案仍在重复。它也不会返回在
cond
表达式中找到的值

以下版本将变量设置为找到的结果。然后,如果找到结果,循环结束,因此可以返回结果

(defun f (item tree)
  (let ((p tree)
        (result nil))
    (while (and p (null result))
      (cond ((equal item (car p)) (setq result p))
            ((and (listp (car p))
                  (equal item (caar p)))
             (setq result (car tree)))
            (t (setq p (cdr p)))))
    result))

除非树可以嵌套数百层,否则就没有必要避免递归。默认递归限制为400。您的重写版本在
(t(f项(cdr p))
行上递归。@Barmar我知道
while
“解决方案”当前是递归的。据我所知,它甚至不起作用;我还没有测试过,这只是我在努力展示的东西,所以这不是一个gimmeh teh codez Q.:)