如何检查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.
答案 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