2

Seasoned Schemerの150ページにある次の関数は、各リストのcdrを変更し、変更が両方に影響したかどうかを確認することで、2つのリストが同じIDを持っている(つまり同じメモリを占有している)かどうかを確認します。

(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. Racket)は、これら2つのリスト(2番目の引数は最初の引数の適切なサブセットであるためメンバーのほとんどを共有する必要があります)が実際には異なるコピーを持っていることを確認します同じメンバー。これはどうして可能ですか?!

このアイデアに少しひねりを加えるには:

(set-cdr! (cddr a_list) a_list)

a_listは循環的です。この関数を使用してテストすると、2つの引数、つまりとsame?が同相の場合にのみ#tが登録されます。 (same? a_list a_list)(same? a_list (cdddr a_list))

[編集回答は、承認された投稿のコメントチェーンの一番下にあります]

4

1 に答える 1

4

このsame?関数は、2つのリストが要素を共有しているかどうかをチェックしません。2つのペア(つまり、2つのconsセル)が同じであるかどうかをチェックします。

(define a_list (list 'a 'b 'c 'd))あなたには4つのペアがあります。(same? a_list (cdr a_list))最初と2番目のペアが同じペアであるかどうかを確認し、同じではないため、を 返しsame?ます#f

に関して:

..そしてデバッガー(Dr. Racket)は、これら2つのリスト(2番目の引数は最初の引数の適切なサブセットであるためメンバーのほとんどを共有する必要があります)が実際には同じメンバーの異なるコピーを持っていることを確認します。これはどうして可能ですか?!

DrRacketでこれをチェックする方法についてもっと正確に教えてください。

2つのリストa-listと(cdr a-list)はメンバーを共有します。

編集:

とが2つの異なる短所セルの名前であるc1とします。c2

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ます。

結論:短所セルが異なる場合、同じですか?#fを返します。


ここで、とが同じconsセルの名前であると仮定c1します。c2

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ます。

結論:短所セルが同じである場合、をsame?返します#f

編集2

consセルが使用するcconsセルの1つであるかどうかを確認するには、次のようにします。l

(define (loop c l)
  (cond
    [(null? l) #f]
    [(same? c l) #t]
    [else (loop c (cdr l))]))
于 2012-06-08T18:45:52.060 に答える