lisp - 如何避免在 cond 子句 LISP 中重复代码?

标签 lisp common-lisp

我应该在 LISP 中找到从根到给定节点的路径。最好使用纯函数方法。

二叉树表示使用子列表,例如: (A (B) (C (D) (E))) - A 是根,B 是 A 的左 child ,C 是 A 的右 child ,D 是 C 和 E 的左 child C 的右 child 。

在我看来,应该有一些方法可以避免重复调用以下函数:

(get-path (cadr l) x)

(get-path (caddr l) x)

我是 LISP 的新手,我不知道也似乎找不到解决方案,但我认为必须有一种 - 纯 - 功能性的方式来做到这一点。也许使用 lambda?不过,不确定如何。我使用了错误的方法吗?非常感谢任何形式的帮助。

;;; l is the list with the binary tree
;;; x is the node we are looking for
(defun get-path(l x) 
    (cond
            ;; nothing to search for anymore
            ((null l) nil)
            ;; found the node we were looking for
            ;; in this case we return a list containing only x
            ((equal (car l) x) (list x))
            ;; the node was found on the left branch
            ((not(equal (get-path (cadr l) x) nil))
                     (cons (car l) (get-path (cadr l) x)))
            ;; the node was found on the right branch
            ((not(equal (get-path (caddr l) x) nil))
                     (cons (car l) (get-path (caddr l) x))))) 

最佳答案

这个呢?

(defun root-path (tree element)
  (when tree
    (cons (first tree)
          (unless (eql (first tree) element)
            (or (root-path (second tree) element)
                (root-path (third tree) element)
                (return-from root-path nil))))))

您甚至应该定义有意义的命名函数,例如 tree-value left-subtreeright-subtree,但这在这里可能有点矫枉过正.

在上面,请注意 when (resp. unless) 在条件失败时用于其 nil 值(resp. succeed ).如果您愿意,可以使用 condif 表达式进行翻译。这里唯一重复的是双 (first tree) 值,它可能会被编译器优化掉,或者手动使用周围的 let 绑定(bind)。

编辑

原始代码无效。解决方案是使用 Joshua 的答案,但我不会复制粘贴到这里,所以我添加了 return-from 表达式。虽然它有效,但您的老师和/或同事可能喜欢这种方法;-)

测试

(mapcar (lambda (n) (root-path '(A (B) (C (D) (E))) n))
        '(a b c d e f))

=> ((a) (a b) (a c) (a c d) (a c e) nil)

关于lisp - 如何避免在 cond 子句 LISP 中重复代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34342606/

相关文章:

lisp - 比较 lisp 中的字符串

javascript - JavaScript 提供了哪些函数式编程方面的子集和类似 Lisp 的特性?

lisp - 子集求和问题和 NP 完全问题的可解性

list - 常用 lisp 函数中的表达式和算术

list - Lisp 反转所有连续的元素序列

list - 在 Common Lisp 中获取列表的前 n 个元素?

lisp - cl-who 中的格式无法正常工作

emacs - 如何从 Emacs 框架 Hook 任何事件/命令?

security - Lisp阅读器输入中的关键字是否危险?

macros - Lisp 宏的问题