Tree 检查节点是否属于树lisp

Tree 检查节点是否属于树lisp,tree,lisp,common-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 t

我必须检查一个节点是否属于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(我想打印消息而不是true或false)

不是数字 =of((3(4))4)个参数的类型应为NUMBER

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

不要把所有的东西都放在一个地方 我想打印一条消息,而不是真或假

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

停止重复那个列表 您使用
元素数持续计算列表中的元素(另请参见)。如果对每个元素执行线性运算,则时间复杂度为二次。要访问树,您只需要区分空列表和非空列表。长度等于1的情况已经得到一般情况的支持

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

同样,我不知道如何到达默认子句
(t(mapcar…)
。这是一个好消息,因为这里的
mapcar
将在每对
(x,y)
元素上应用
#ver
,其中
x
取自
(cdr树)
,而
y
取自
e
!结果就是一个列表!由于您正在查找匹配项,因此可以使用,但您已经可以在
listp
子句中介绍该情况。 -
(listp(cartree))
如果您的第一个元素是一个列表,您可以使用该列表递归调用函数,但是
(cdr 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
不是数字 =of((3(4))4)个参数的类型应为NUMBER

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

不要把所有的东西都放在一个地方 我想打印一条消息,而不是真或假

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

停止重复那个列表 您使用
元素数持续计算列表中的元素(另请参见)。如果对每个元素执行线性运算,则时间复杂度为二次。要访问树,您只需要区分空列表和非空列表。长度等于1的情况已经得到一般情况的支持

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

同样,我不知道如何到达默认子句
(t(mapcar…)
。这是一个好消息,因为这里的
mapcar
将在每对
(x,y)
元素上应用
#ver
,其中
x
取自
(cdr树)
,而
y
取自
e
!结果就是一个列表!由于您正在查找匹配项,因此可以使用,但您已经可以在
listp
子句中介绍该情况。 -
(listp(cartree))
如果您的第一个元素是一个列表,您可以使用该列表递归调用函数,但是
(cdr 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

我更熟悉Lisp的Scheme方言,其中将编写
member
函数:

(define (member? tree e)
  (if (not (pair? tree))
      (equal? tree e)
      (or (member? (car tree) e)
          (member? (cdr tree) e))))
在通用Lisp中,它应该是:

(defun tree-member (tree e)
  (if (atom tree) ; alternatively: (not (consp tree))
      (equal tree e)
      (or (tree-member (car tree) e)
          (tree-member (cdr tree) e))))

你可以考虑用一个默认值来做相等谓词的另一个参数。

< P>我比较熟悉LISP的方案方言,其中<<代码>成员< /C>函数将被写成:

(define (member? tree e)
  (if (not (pair? tree))
      (equal? tree e)
      (or (member? (car tree) e)
          (member? (cdr tree) e))))
在通用Lisp中,它应该是:

(defun tree-member (tree e)
  (if (atom tree) ; alternatively: (not (consp tree))
      (equal tree e)
      (or (tree-member (car tree) e)
          (tree-member (cdr tree) e))))

你可以考虑用默认值来做一个相等的谓词。< /P>如果我这样运行(VER(1 2(3(4)))4),它会给我一个错误:In=((3(4))4)参数应该是类型号。如果我像这样运行(VER(1 2(3(4)))),它会给我一个错误:In=((α))参数的类型应为NUMBER。^

;或者:(not(consp tree))
-
atom
在历史上缺乏
-p
,但
cons