tree - 检查节点是否属于 tree lisp

标签 tree lisp common-lisp

我必须检查一个节点是否属于 lisp 中的一棵树,但我不知道为什么它不起作用。

这是我的代码:

(defun number-of-elems (l)
  (cond
    ((null l) 0)
    (t (1+ (number-of-elems (cdr l))))))


(defun ver (tree e)
  (setq message1 "The node belongs to the tree.")
  (setq message2 "The node does not belong to the tree.")
  (cond
    ((null tree) nil)
    ((= (number-of-elems tree) 1)
     (cond
       ((= (car tree) e) (princ message1))
       (t (princ message2))))
    ((> (number-of-elems tree) 1)
     (cond
       ((listp (car tree)) (ver (car tree) e))            
       ((atom (car tree)) 
        (cond
          ((equal (car tree) e) (princ message1))
          (t (ver (cdr tree) e))))
       ((number (car tree)) 
        (cond
          ((= (car tree) e) (princ message1))
          (t (ver (cdr tree) e))))
       (t (mapcar #'ver (cdr tree) e))))))

这是它应该如何工作的一个例子:

树是 (a (b (c)) (d) (e (f))) 节点是 b => true(我想打印消息而不是真或假)

最佳答案

不是数字

= of ((3 (4)) 4) arguments should be of type NUMBER

错误来自(= (car tree) e),因为你假设如果tree只有一个元素,那么这个元素必然是一个数字。这里,单例的car本身就是一个列表,这使得=失败。

不要把所有东西都放在一个地方

I wanted to print a message instead of true or false

定义另一个 调用第一个函数的函数,它返回 T 或 NIL,否则您将无法重用您的代码。 此外,(setq message1) 不是您想要的,因为它修改了 message1 符号的全局绑定(bind)。一个人会使用 let ,但是此处如果您只是执行 (princ (if (ver ...) "Ok""Not found")),则不需要它。

停止迭代该列表

您可以使用 number-of-elems 对列表中的元素进行计数(另请参阅 length)。如果您对每个元素执行线性运算,您将具有二次时间复杂度。为了访问一棵树,您只想区分空列表和非空列表。一般情况下已经支持长度等于1的情况。

删除死代码

(number (car tree)) 应该是 (numberp (car tree))(注意 p)。但更重要的是,与这个子句相关的代码是死代码:如果你有一个数字,它就是一个原子,并且与前面的子句匹配。此外,使用 equal 进行测试也适用于数字。

同样,我看不到如何到达默认子句 (T (mapcar ...))。这是一个好消息,因为这里 mapcar 将在每对 (x,y) 元素上应用 #'ver,其中 x 取自 (cdr tree)y 来自 e !结果是一个列表!由于您正在寻找匹配项,因此可以使用 some相反,但您已经可以在 listp 子句中涵盖这种情况。 - (listp (car tree)) 如果您的第一个元素是一个列表,您可以使用该列表递归调用该函数,但是 (cdr tree) 呢?在 (car tree) 中找到该元素,未找到该元素,您应该尝试使用其余元素。

提示

这是你想要的执行轨迹:

    0: (ver (1 2 (3 (4))) 4)
      1: (ver 1 4)
      1: ver returned nil
      1: (ver 2 4)
      1: ver returned nil
      1: (ver (3 (4)) 4)
        2: (ver 3 4)
        2: ver returned nil
        2: (ver (4) 4)
          3: (ver 4 4)
          3: ver returned t
        2: ver returned t
      1: ver returned t
    0: ver returned t

关于tree - 检查节点是否属于 tree lisp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34292264/

相关文章:

emacs - 如何在 emacs org-mode 的议程 View 中只显示一次 SCHEDULED 和 DEADLINE's todo

lisp - ' ('(LIST) ' 无 'NIL) should be a lambda expression in (hanoi(' ('(list)' ()'())))

lisp - 口齿不清错误 : Expected-type: REAL datum: NIL

function - 将函数作为参数传递 - lambda 表达式错误?

c++ - 如何循环进入同名节点

java - MapTreeStructure 导出为 map

macros - 完全展开一个宏窗体

scheme - 截断(受限) Racket 中的列表

使用B+树创建索引文件

javascript - 从对象列表中创建 javascript 树