检查节点是否属于树lisp

时间:2015-12-15 14:52:17

标签: 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 =>是的(我想打印一条消息而不是真或假)

2 个答案:

答案 0 :(得分:3)

不是数字

  

= of((3(4))4)参数应为NUMBER

类型

错误来自(= (car tree) e),因为您假设如果tree只有一个元素,则此元素必须是数字。在这里,单身人士的car本身就是一个列表,这使=失败。

不要把所有东西混合在一个地方

  

我想打印一条消息而不是真或假

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

停止迭代该列表

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

删除死码

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

同样,我也不知道如何达到默认条款(T (mapcar ...))。这有点是一个好消息,因为mapcar #'ver会在每对(x,y)元素上应用x,其中(cdr tree)取自y和{{1}来自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

答案 1 :(得分:1)

我更熟悉Lisp的Scheme方言,其中将编写globals[eachLine dates openPrices highPrices lowPrices closePrices volumes] to openFile file-open "jqr.txt" set dates [] set openPrices [] set highPrices [] set lowPrices [] set closePrices [] set volumes [] set fileList [] while [not file-at-end?] [ set csv file-read-line set csv word csv "," ; add comma for loop termination let mylist [] ; list of values while [not empty? csv] [ let $x position "," csv let $item substring csv 0 $x ; extract item carefully [set $item read-from-string $item][] ; convert if number set mylist lput $item mylist ; append to list set csv substring csv ($x + 1) length csv ; remove item and comma ] set fileList lput mylist fileList ] ;; ?????? foreach fileList show fileList file-close end 函数:

member

在Common Lisp中它应该是:

(define (member? tree e)
  (if (not (pair? tree))
      (equal? tree e)
      (or (member? (car tree) e)
          (member? (cdr tree) e))))

您可以考虑使用默认值使等式谓词成为另一个参数。