2017-01-25 8 views
0

のn番目の要素を削除して、私は()(」1 2 3 4 Dを定義)ない場合は、リストこんにちはリスト

(define (delete l n) 
    (if (= n 1) 
     (begin (set! l (cdr l)) 
      l) 
     (begin (set-cdr! (n_sub_list (- n 1) l) 
         (cdr (n_sub_list n l))) 
      l))) 

      (define n_sub_list n l) 
        (if (= n 1) l 
       (n_sub_list (- n 1) (cdr l)))) 

のn番目の要素を削除するには、次の手順を書き、 (削除!d 2)私はそれが(1 3 4)ですが、私は継続して(削除!d 1)を行う場合、私は(1 3 4)が間違っている理由は何ですか?

答えて

1

コードには、何かを変更する2つの異なる手順があります。

あなたはset-cdr!を持っていますが、これは引数の対のcdrが何を指しているかを変更します。これは、変更可能なリストでのみ発生します。 '(1 2 3 4)は不変のリストであるため、結果は未定義です。 (list 1 2 3 4)でそれを行うことは、変更可能なリストになるので大丈夫です。

set!には、名前付き変数が表すものが再定義されています。名前が実際に指す値は変更されません。 lというラベルは、前の値以外の何かを意味しています。これは、dが依然としてあなたのケースで参照しているためです。

私は私の友人を茶色にしていると呼んでいます。半年で私は停止し、別の友人を代わりにグリーンホーンと呼ぶようになります。私の元の友人は存在しなくなったり、私の他の友人になり、他の友人は彼の人生を引き継ぎません。唯一の実際の変更は、pafがニックネームに関連付けられているものです。これはset!の機能です。これは、同じ名前を持つ、最も近いとそれをしない

(define a 5) 
(define b 10) 
(let ((a 10)) 
    (set! b 20) 
    (set! a 20) 
    a) 
; ==> 20 
b 
; ==> 20 
a 
; ==> 5 

aが変更さは変わらないグローバルaを残しletで行われた現地ました。

Schemeの手続きは、あなたが返すものをそう変異してはならない重要なのです:

(define (delete l n) 
    (cond ((or (null? l) (< n 1)) l) 
     ((= n 1) (cdr l)) 
     (else (cons (car l) 
        (delete (cdr l) 
          (- n 1)))))) 

(set! d (delete d 1)) 
+0

だから私は設定しているので!関数では、私は望みの結果を返しますが、元の変数dを変更することはありませんし、あなたのコードでは、私は望みの結果を得て元のリストdに割り当てます。そして、これを行うことによって、 "削除"、そう? – user7054784

+0

@ user7054784はい。あなたは価値を変えることはありませんが、特定の束縛を変えます。ほとんどの言語で同じことが成り立ちますが、そのほとんどは価値のあるものです。 – Sylwester