2012-06-08 64 views
2

以下函數從的第150頁的經驗證示意圖通過變更每個列表的cdr來確定兩個列表是否具有相同的身份(即佔用相同的內存),然後檢查是否變化已經影響到這兩個:測試兩個對(cons單元格)是否相同

(define same? 
(lambda (c1 c2) 
    (let ((t1 (cdr c1)) 
     (t2 (cdr c2))) 
    (set-cdr! c1 1) 
    (set-cdr! c2 2) 
    (let ((v (= (cdr c1) (cdr c2)))) 
     (set-cdr! c1 t1) 
     (set-cdr! c2 t2) 
     v)))) 

現在,如果我定義a_list如下:

(define a_list (list 'a 'b 'c 'd)) 

和評估

(same? a_list (cdr a_list)) 

函數返回#f,調試器(Dr.)球拍)證實,這兩個名單 - 自第二個參數以來應該分享他們的大部分成員是第一個的真正子集 - 確實具有相同成員的不同副本。這怎麼可能?!

有關這個想法輕微的扭曲:

(set-cdr! (cddr a_list) a_list) 

現在a_list是週期性的。如果我用same?測試這個函數,它只在兩個參數同相位時註冊#t,即(same? a_list a_list)(same? a_list (cdddr a_list))

[編輯答案是在接受後的評論鏈的底端]

回答

4

same?功能不會檢查是否兩個列表共享元素。 它檢查兩對(即兩個cons單元)是否相同。

(define a_list (list 'a 'b 'c 'd))你有4對。 在(same? a_list (cdr a_list))你檢查第一個 和第二對是否是同一對,並且因爲它們不是,所以 same?返回#f

關於:

..和調試器(球拍博士)證實,這兩個名單 - 這 應該,因爲第二個參數是一個 真子集,分享他們的大部分成員第一個 - 實際上有相同成員的 不同的副本。這怎麼可能?!

您能更準確地瞭解您在DrRacket中的檢查方式嗎?

兩個列表a-list和(cdr a-list)共享成員。

編輯:

假設c1c2是兩個不同的利弊細胞名稱:

c1: (foo . bar)  c2: (baz . qux) 

現在我們評估(set-cdr! c1 1)並獲得:

c1: (foo . 1)  c2: (baz . qux) 

現在我們評估(set-cdr! c2 2)並獲得:

c1: (foo . 1)  c2: (baz . 2) 

然後我們比較cdrs(= (cdr c1) (cdr c2))。 由於cdrs是不同的,我們得到#f

結論:當cons細胞不同,相同?返回#f。


現在假設c1c2是相同的利弊單元名稱:

c1 = c2: (foo . bar) 

現在我們評估(set-cdr! c1 1)並獲得:

c1 = c2: (foo . 1) 

現在我們評估(set-cdr! c2 2)並獲得:

c1 = c2: (foo . 2) 

然後我們比較cdrs(= (cdr c1) (cdr c2))。 由於cdrs是相同的,我們得到#t

結論:當cons單元格相同時,same?返回#f

編輯2

要檢查cons單元c是否是l使用 缺點小區中的一個這樣的:

(define (loop c l) 
    (cond 
    [(null? l) #f] 
    [(same? c l) #t] 
    [else (loop c (cdr l))])) 
+0

**它檢查2對(即,兩個缺點細胞)是否在** 'same?'聲稱表明兩個對佔用相同的內存,但我不清楚該算法是如何區分與共享成員的對相同的對。 **您可以更加精確地瞭解您在DrRacket中的檢查方式嗎?** 我正在逐步使用R5RS中的調試程序代碼 – planarian

+1

@Planarian(A。(BCD))!=(B。( CD))「這是'相同'檢查的*唯一*的東西。它並不關心自己在這些* cdr *列表中尋找共享結構。 –

+0

@Planarian我加了一個解釋'same?'是如何工作的。 – soegaard

相關問題