6

我有一个函数,它接受一个包含两个或三个元素的列表。

;; expecting either ((a b c) d) or ((a b c) d e)
(define (has-third-item ls)
      (if (null? (caddr ls))
          false
          true)
      )

但是这段代码失败了

mcar: expects argument of type <mutable-pair>; given ()

在 (null? (caddr ls)) 表达式上。

我也试过

(eq? '() (caddr ls))

但它也没有用。如何判断是否有第三项?

4

5 回答 5

10

您不想要 caddr,您想要 (if (null? (cddr ls)) ... 或者只是使用 length 来查找列表的长度,并将其与您感兴趣的值进行比较。

终止列表的 '() 将始终位于一对的 cdr 位置,因此在 car 位置(cad+r 会这样做)寻找它不会有成效。

于 2009-03-19T22:30:14.110 回答
5

问题是,如果您有一个包含两个或更少项目的列表,则无法获取它的 caddr。试试这个:

(define (has-third-item lst)
  (<= 3 (length lst)))

在某些情况下,获取列表的长度可能效率低下(例如包含数百万个项目的列表);在这种情况下,我们可以手动测试列表的长度是零、一还是二:

(define (has-third-item lst)
  (not (or (null? lst)
           (null? (cdr lst))
           (null? (cddr lst)))))

编辑:关于其他两个 答案,虽然在这种情况下使用 cddr 可能会起作用,因为输入域由具有两个或三个元素的列表组成,对于具有零或一的列表,has-third-item 仍然会失败。为了通用性,我建议使用适用于任何领域的解决方案。

于 2009-03-19T22:31:51.767 回答
1

如果您知道您的列表有两个或三个元素(正如您所说的那样),您可以这样做

(define (has-third-item? l)
  (not (null? (cddr l))))

您正在检查第二个 cons 单元格(cddr l)是否有 a cdr。您不必检查 l 本身是否为 null 或 l 是否只有一个元素,除非您想要更通用的函数。

于 2009-04-06T12:37:38.543 回答
0

尝试...

(and l (cdr l)(cddr l))
于 2009-04-08T11:56:22.747 回答
0

为什么不使用(第三个ls)

如果不存在,将返回第三个元素或 NIL。

于 2009-04-08T13:42:11.603 回答