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。
添加回答
舉報