3 回答
TA贡献1824条经验 获得超6个赞
Scheme或任何其他LISP方言中的点表示法用于创建任意两个值的点对。值可以是符号,列表或其他任何值。究竟是什么值并不重要。例如:
'(author . aaditmshah) => (author . aaditmshah)
'((a b c) . (d e f)) => ((a b c) d e f)
如您所见,如果创建两个列表的点对,则第一个列表将添加到第二个列表的开头。这是因为LISP中的列表是嵌套的虚线对:
'(a . (b . (c . ()))) => '(a b c)
因此,在编写'((a b c) . (d e f))时就像在编写以下内容:
'((a b c) . (d . (e . (f . ())))) => '((a b c) d e f)
这是完全有效的。您仍然可以使用car和cdr通常那样分别访问两个列表:
(car '((a b c) . (d e f))) => (a b c)
(cdr '((a b c) . (d e f))) => (d e f)
我不确定您的compare-attrs功能应该做什么。您的if分支返回一个cons单元格,而您的else分支返回一个布尔值。对我来说,这完全没有道理。函数的返回类型应该是一致的。
也许您没有正确表达您的问题,因为我不确定您的问题是什么。让我知道您是否还有任何疑问。
TA贡献1784条经验 获得超8个赞
我对方案中数据结构的回忆是,您希望避免使用(a . b)点对点的原子(即),因为这代表将两个原子精简在一起的结果。如果查看第3页的小计划者,您将看到以下内容:
缺点法则
基本缺点有两个参数。缺点的第二个参数必须是列表。结果是一个列表。
如果您已阅读其他答案,那么您就会知道这不是事实。坦白说,与SICP禁止的Scheme数据结构有关的事情是,以列表的形式定义数据结构的布局,然后几乎不充当访问器的功能。
因此,假设您想要一个元组-您可以使其看起来像是(a b)完全合理的。然后,您可以编写以下功能:
(define (make-tuple a b) (list a b))
(define (tuple-first tup) (car tup))
(define (tuple-second tup) (car (cdr tup)))
(define (tuple? tup) (and (list? tup) (eq? 2 (length tup))))
现在,它为我提供了访问器函数和一个构造函数,我是金。但这并不是说这是唯一的方法。您可以继续使用配对:
(define (make-tuple a b) (cons a b))
(define (tuple-first tup) (car tup))
(define (tuple-second tup) (cdr tup))
(define (tuple? tup) (pair? tup))
因此,在您的代码中,您可以在此处使用构造函数来创建所需的元组。
通常,您的compare-attrs函数很奇怪,因为该名称并不能真正让我们了解您要执行的操作。我更倾向于这样写:
(define (compare-attrs a1 a2)
(or
(and (null? a1) (null? a2))
(and (not (null? a1)) (not (null? a2)))
))
(define (join-populated-attrs a1 a2)
(if (compare-attrs a1 a2) (make-tuple a1 a2) '()))
仍然很有趣,因为您正在接受两个null属性,但这可能是整个问题域的一部分。
我还应该说,如果您希望输出以特定的方式出现,则可能也应该编写print-tuple。
添加回答
举报