algorithm - 如何将这种递归解决方案转换为迭代解决方案?

标签 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)))))))

此函数接收一棵和一个以在其直接叶子中查找。如果 item 是任何子列表的汽车,那么它将返回该子列表。也就是说,

  • (f 'c '(a b c)) => (c)
  • (f 'b '(a b c)) => (b c)
  • (f 'a '((a 1 2) b c)) => (a 1 2)

我最近被告知 (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)))))

为了简洁/清晰,我缩短了函数名称,但请查看 where it is being used如果您是 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))

关于algorithm - 如何将这种递归解决方案转换为迭代解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26696127/

相关文章:

parsing - 递归解析组织模式层次结构

emacs - 为什么不让*默认让?

c++ - 基于单元框架的算法性能测试的可靠性

lisp - 如何将最大值导入 sbcl

emacs - 为所有事件缓冲区重新加载 .emacs

LISP:使用 RPLACA/RPLACD/NCONC 反转 LISP 中的列表

emacs - 如何检查 Emacs 中是否存在当前缓冲区?

algorithm - 比较二进制堆的插入操作

java - HashMap 空间复杂度

java - 没有正则表达式的单词模式