Lisp - 如何检查列表是否为点对?

时间:2012-06-17 14:31:14

标签: list lisp common-lisp predicate

如何检查lisp中的列表是否为点对?

CL-USER 20 : 3 > (dotted-pair-p (cons 1 2))
T

CL-USER 20 : 3 > (dotted-pair-p '(1 2))
NIL

CL-USER 20 : 3 > (dotted-pair-p '(1 2 3))
NIL

我尝试检查length=2是否有错误:

CL-USER 28 : 1 > (= (length (cons 2 3)) 2)
Error: In a call to LENGTH of (2 . 3), tail 3 is not a LIST.

5 个答案:

答案 0 :(得分:9)

“点对符号”中的lisp列表如下所示:

(1 . ()).

由于这是家庭作业,我会让你把它归结为合乎逻辑的结论。比较

(LIST 1 2) => (1 . (2 . ()))

(CONS 1 2) => (1 . 2).

这两者有什么不同?你怎么能用谓词来区分呢?

请记住所有正确的lisp列表以空列表结尾。问问自己,你如何获得一对利弊的第二个元素?那里的解决方案应该很明确。

答案 1 :(得分:2)

因为列表总是以空列表结束,而一对不是:

(listp (cdr '(1 2))) => T
(listp (cdr '(1 . 2))) => NIL

答案 2 :(得分:0)

(not(listp(cdr (cons 1 2))))=> T
(not(listp(cdr (list 1 2))))=> nill

答案 3 :(得分:0)

您可以使用以下命令检查列表是否带点缀(以非零原子结尾)

(defun dotted-listp (l)
  (cond ((null l) nil)
        ((atom l) t)
        (t (dotted-listp (cdr l)))))

答案 4 :(得分:0)

点对是一个cons单元格,它的CDR本身不是一个cons(递归定义)。因此,此'(1 . 2)是点对,但不是'(1 . ()),因为它只是'(1)的印刷表示形式。

(defun dotted-pair-p (x)
  (and (consp x)
       ;; Check that CDR is not a list with LISTP
       ;; since (CONSP ()) ;;=> NIL
       ;; and the CDR of a pair can't be NIL for it
       ;; to be dotted.
       (not (listp (cdr x)))))

(dotted-pair-p '(1 . 2))            ;T
(dotted-pair-p '(1 . ()))       ;NIL

点分列表(最后一个cons单元为点分的列表)由LIST*在Common Lisp中定义。现在,我们也可以使用上述功能为它们定义谓词:

(defun list*p (x)
  (dotted-pair-p (last x))) 

(list*p (list* 1 2 3 4))        ;T
(list*p (list 1 2 3 4))         ;NIL