2017-02-27 21 views
1

DAGをトラバースするための宿題割り当てに取り組んでいます。いくつかのSOの答えの助けを借りて、私は場所にかなりの部分を持っています。つまり、データをさらに処理する必要があるように、サブリストのリストを返す関数を取得するのに問題があります。サブリストをリスト形式で保存する

((B3 B5の57:データファイルは、私は(?子供B3)を実行すると、私がどのように見える結果を得る形でのサブリストのリスト(ノード1ノード2重量)

(define (children? node) 
    (define list '(1)) 
    (map (lambda (x) 
     (cond 
      ((equal? (car x) node) 
      (if (equal? list '(1)) 
       (set-car! list x) 
      (append! list x))))) 
    data) 
(if (equal? list '(1)) 
    #f 
    list)) 

(define (append! lst . lsts) 
    (if (not (null? lsts)) 
    (if (null? (cdr lst)) 
     (begin 
     (set-cdr! lst (car lsts)) 
     (apply append! (car lsts) (cdr lsts))) 
     (apply append! (cdr lst) lsts)))) 

を持っています実際に

((B3、B5 57)(B3 B4 81)(B3 B10 55)(B3 B14 61)(

ようになります)B3 B4 81 B3 B10 55 B3 B14 61 B3 B13 66)

b3 b13 66))

ここで私の問題を明るくする?

ご協力いただきありがとうございます。

+1

あなたのインデントはすべて間違っている、あなたはそれが必要でない場合は破壊的なリストの変更を使用しないでください、と 'data'が実際にどのように見えるかの例を提供しなければならないはずです。つまり、おそらく 'list'や' cons'を使うべきであるところに 'append'を使っています。 –

答えて

1

インデントを修正、あなたのコードは、頭のセンチネルトリックを使用して

(define (children? node) 
    (define list '(1)) 

になります。良い(まあ...)。しかし、その目的は外科的に改造されているので、引用したデータではなく、新しく作成する必要があります。

(define list (list 1)) 

待つ、何ですか? 2つlist?これはCommon Lispではありませんか? SchemeはLisp-1ではなく、Lisp-2です。関数と値の名前は同じ名前空間にあります。そう;しないでください。行の

(define lst (list 1)) 

    (map (lambda (x) 
     (cond 
      ((equal? (car x) node) 
       (if (equal? list '(1)) 
        (set-car! list x) 
        (append! list x))))) 

2つの条件はただandですが、より重要なのは、頭のセンチネルトリックは、あなたが(cdr lst)として真の結果を返します意味、とてもその頭の内容を変更する必要はありません。

(map (lambda (x) 
     (if (equal? (car x) node) 
      (append! lst x)))  ; changed the name 

ない代替句:コードは、最初の場所でヘッドセンチネルを使用して、全体の目的である、簡略化?一般的には、眉をひそめますが、ここではその副作用のための地図を作成しますので、でない限り、mapの結果を使用しても問題ありません。より簡単にはかかわらず、ちょうどは常に

(map (lambda (x) 
     (if (equal? (car x) node) 
      (append! lst x) ; append two lists together... (see below) 
      #f)) 
     data) 

dataのように、習慣と良いスタイルの問題として代替句を処理するためにありますか?それは何ですか?別の仮パラメータchildren?として追加する必要があります。

(if (equal? lst '(1)) 

equal??どうして?我々はそれを変更してあるかどうかを確認するには、それだけで

(if (null (cdr lst)) 

少なくともアクション原則に十分です...

 #f 
     (cdr lst))) ; cdr carries the true payload 

(だから、基本的には、

(define (children? node data) 
    (let ((res (filter (lambda (x) (equal? (car x) node)) 
         data))) 
     (if (not (null? res)) 
     res 
     #f))) 

)。良い。それは...ですか?さて、以下のことが正しく働いているかどうかにかかっています。それ

(define (append! lst . lsts) 
    (if (not (null? lsts)) 
     (if (null? (cdr lst)) 
     (begin 
      (set-cdr! lst (car lsts)) 
      (apply append! (car lsts) (cdr lsts))) 

リストを追加し、そう(append! (list 1) (list 2))(list 1 2)(append! (list 1) (list 2 3))(list 1 2 3)と同じと同じ結果を返します。リストの最後にアイテム(例えば2のようなもの)を追加するには、最初に別のリストの中に入れなければなりませんでした。したがって、追加されるアイテムがそれ自体リストである場合、'(2 3)のように、'(1 (2 3))を戻したいと考えています。そしてそのためには、項目を追加する前にリストに囲む必要があります。だからあなたの機能を修正しなければなりません。

 (apply append! (cdr lst) lsts)))) 

そしてここで、あなたは何度も再び追加された項目ごとに、その最後のセルを見つけるためにあなた(成長)結果のリストをスキャンします。最後のセルポインタを自分自身で維持し、それを直接使用することでこれを改善できます。その "ポインタ"は何ですか?それはlstです。あなたはcdrあなたのたびにappend!何かにそれ;だからあなたは(set-cdr! lst (list item))を直接あなたのことをすることができます。もちろん、lstという変数を使用することはできません(なぜ?)。

1

あなたのコードでは、Algolのプログラミング経験(CやJavaなど)の知識を適用してSchemeを学習しているようです。 Schemeでは、そうする本当の理由がない限り、突然変異なしでプログラミングを行うべきです。手続きのほとんどを純粋に保つことは、テストが簡単であることを意味します。

命名規則は重要であり、終了する手順は?は述語であるため、のように#tまたは#fという2つの値のいずれかを返して、Algol言語でtrue/falseを返す必要があります。

;; graph constructor/accessors not not use car, cadr, etc 
;; later you can change it to boxes 
(define (make-graph from to weight) 
    (list from to weight)) 
(define graph-from car) 
(define graph-to cadr) 
(define graph-wight cddr) 

;; gets the graphs that has node as starting point 
(define (graphs-from node graphs) 
    ; match? returns #t if graph starting point is the same as node 
    ; since it's symbols we use eq? 
    (define (match? graph) 
    (eq? node (graph-from graph))) 

    ; filters data by starting point 
    ; this is the tail expression and thus the result of this procedure 
    (filter match? graphs)) 

(define data (list (make-graph 'x 'y 20) 
        (make-graph 'y 'x 30) 
        (make-graph 'w 'e 20) 
        (make-graph 'x 'e 13))) 

(graphs-from 'x data) 
; ==> ((x y 20) (x e 13)) 

(graphs-from 'a data) 
; ==>() 
関連する問題