2016-04-26 6 views
1

問題

私はラケット機能書き込むための割り当てがあります。ラケットデータ処理問題:ベクトルのポインタがvoidの

は、宛先(3文字の空港コードの両方)、起源を取るを、 とフライトデータのリストを返し、最初の要素としてコンシューマ セル(起点。目的地)を使用して、起点から目的地までのすべてのフライトについて遅滞統計情報リスト を返します。

データは、少なくとも1,15,30,60,120、および180分遅れのフライトの比率で6つの比率でフォーマットする必要があります。

以下のコードでは、一致する飛行データが見つかるたびに、長さ6のベクトルの値をインクリメントする末尾の再帰関数を書きました。その後、データのリストが再帰的にチェックされると、割合のリストが返されます。

インクリメントコードに達したときにpartが無効であることを示す次のエラーが表示されます。 partは、関数全体を通して生成されたベクトルを指してはいけませんか?

エラー

vector-ref: contract violation 
    expected: vector? 
    given: #<void> 
    argument position: 1st 
    other arguments...: 3 

コード

(require "ontime.rkt") 

(define (ontime-stats-by-route orig dest data) 
    (define (aux orig dest data part) 
    (if (null? data) 
     (let ([sum (foldl + 0 (vector->list part))]) 
      (list (cons orig dest) 
       (/ (vector-ref part 0) sum) 
       (/ (vector-ref part 1) sum) 
       (/ (vector-ref part 2) sum) 
       (/ (vector-ref part 3) sum) 
       (/ (vector-ref part 4) sum) 
       (/ (vector-ref part 5) sum))) 
     (if (and 
      (eq? orig (car (car (cdr (car data))))) 
      (eq? dest (car (cdr (car (cdr (car data))))))) 
      (let ([late (car (cdr (cdr (cdr (car data)))))]) 
       (cond 
       [(>= late 180) (aux orig dest (cdr data) 
            (vector-set! part 5 (vector-ref part 5)))] 
       [(>= late 120) (aux orig dest (cdr data) 
            (vector-set! part 4 (vector-ref part 4)))] 
       [(>= late 60) (aux orig dest (cdr data) 
            (vector-set! part 3 (vector-ref part 3)))] 
       [(>= late 30) (aux orig dest (cdr data) 
            (vector-set! part 2 (vector-ref part 2)))] 
       [(>= late 15) (aux orig dest (cdr data) 
            (vector-set! part 1 (vector-ref part 1)))] 
       [(>= late 1) (aux orig dest (cdr data) 
            (vector-set! part 0 (vector-ref part 0)))] 
       [else (aux orig dest (cdr data) part)])) 
      (aux orig dest (cdr data) part)))) 
    (let ([count (make-vector 6 0)]) 
    (aux orig dest data count))) 

(ontime-stats-by-route "BWI" "BDL" ontime) 
+1

ラケット '#'はヌルポインタではなく、通常はヌル値には使用されません。通常、副作用があるため、有用な価値を返さない手続きに由来します。 –

答えて

3

問題彼らは彼らの突然変異ではなく、その戻り値に使用しているのでなどvector-set!set-box!、などのミューテータ関数は#<void>を返すということです。これは、明確で機能的なコード(あなたが好きなように操作して並べ替えることができる)と明確に命令的なコード(より慎重でなければならない)との間の分離を促すためです。これは、これらの機能が通常!で終わる理由です。

代わりに新しいpart引数としてで(vector-set! part ....)を渡すので、あなたは別に、この変異を行い、その後、それが今で変異しています代わりにするので、引数としてpart自体を渡す必要があります。

  (cond 
      [(>= late 180) 
      (vector-set! part 5 (vector-ref part 5)) 
      (aux orig dest (cdr data) part)] 
      [(>= late 120) 
      (vector-set! part 4 (vector-ref part 4)) 
      (aux orig dest (cdr data) part)] 
      [(>= late 60) 
      (vector-set! part 3 (vector-ref part 3)) 
      (aux orig dest (cdr data) part)] 
      [(>= late 30) 
      (vector-set! part 2 (vector-ref part 2)) 
      (aux orig dest (cdr data) part)] 
      [(>= late 15) 
      (vector-set! part 1 (vector-ref part 1)) 
      (aux orig dest (cdr data) part)] 
      [(>= late 1) 
      (vector-set! part 0 (vector-ref part 0)) 
      (aux orig dest (cdr data) part)] 
      [else 
      (aux orig dest (cdr data) part)]) 

(vector-set! part 5 (vector-ref part 5))のようなものがAREN、が、インデックス5の値を変更するつもりはありません。値を増やしたかったとしたら、(vector-set! part 5 (add1 (vector-ref part 5)))を意味しましたか?

  (cond 
      [(>= late 180) 
      (vector-set! part 5 (add1 (vector-ref part 5))) 
      (aux orig dest (cdr data) part)] 
      [(>= late 120) 
      (vector-set! part 4 (add1 (vector-ref part 4))) 
      (aux orig dest (cdr data) part)] 
      [(>= late 60) 
      (vector-set! part 3 (add1 (vector-ref part 3))) 
      (aux orig dest (cdr data) part)] 
      [(>= late 30) 
      (vector-set! part 2 (add1 (vector-ref part 2))) 
      (aux orig dest (cdr data) part)] 
      [(>= late 15) 
      (vector-set! part 1 (add1 (vector-ref part 1))) 
      (aux orig dest (cdr data) part)] 
      [(>= late 1) 
      (vector-set! part 0 (add1 (vector-ref part 0))) 
      (aux orig dest (cdr data) part)] 
      [else 
      (aux orig dest (cdr data) part)])