【问题标题】:Lisp - How can I check if a list is a dotted pair?Lisp - 如何检查列表是否为点对?
【发布时间】:2012-06-17 14:31:13
【问题描述】:

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

【问题讨论】:

  • 还要注意,所有正确的列表都是特定形式的点对。
  • 看看我的回答,想想两者有什么不同。 length 将假设有一个空列表。这就是它知道停止的方式。
  • (= (length (cons 2 3) 2)) 应该是(= (length (cons 2 3)) 2)

标签: list lisp common-lisp predicate


【解决方案1】:

“点对表示法”中的 lisp 列表看起来像:

(1 . ()).

既然这是作业,我会让你得出合乎逻辑的结论。比较

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

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

这两者有什么不同?您如何使用谓词来区分?

记住所有正确的 lisp 列表都以空列表结尾。问问自己如何访问缺点对的第二个元素?那里的解决方案应该很清楚。

【讨论】:

  • 区别是第一个列表最后有一个空列表,第二个没有,但是hoe=w我能查到吗?
  • 问问自己,在普通的 lisp 中,空列表是如何表示的? (eq '() ??) 填??在。当然,您需要访问 cons 对的第二个元素。你学过哪些功能?浏览它们并将拼图拼凑在一起。
  • '(1 . ()) 不是虚线列表,它只是(1)
【解决方案2】:

因为列表总是以空列表结尾,而一对则不会:

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

【讨论】:

    【解决方案3】:
    (not(listp(cdr (cons 1 2))))=> T
    (not(listp(cdr (list 1 2))))=> nill
    

    【讨论】:

    • 这个答案需要一些解释才能有用;请对其进行编辑以包含一些内容。
    【解决方案4】:

    点对是一个 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 单元格为点的列表)在 Common Lisp 中由 LIST* 定义。我们现在也可以使用上面的函数来为它们定义一个谓词:

    (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
    

    【讨论】:

      【解决方案5】:

      您可以使用以下方法检查列表是否点缀(以非零原子结尾):

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

      【讨论】:

      • (dotted-listp 1) 返回 T
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 2011-09-02
      • 1970-01-01
      • 2016-03-21
      • 2017-02-12
      • 2011-09-07
      • 1970-01-01
      相关资源
      最近更新 更多