0

Ngrams プログラムに取り組んでいますが、ハッシュ テーブルの入力に問題があります。単語を取得してハッシュテーブルに追加する再帰関数を書きたいと思います。データセット 1 2 3 4 5 6 7 が与えられた場合の動作方法は、ハッシュテーブルの最初のエントリのキーが [1 2] で、データが 3 である必要があります。2 番目のエントリは [2 3] のようになります。 ] であり、そのデータは 4 であり、テキスト ファイルの最後まで続く必要があります。

テキストから 1 単語を返すだけの readword という事前定義された関数が与えられます。しかし、これらの呼び出しを互いにオーバーラップさせる方法がわかりません。データがハードコードされている場合、呼び出しは次のようになります。

(hash-set! (list "1" "2") 3 
(hash-set! (list "2" "3") 4

私が試した2つの呼び出しは次のようになります

  (hash-set! Ngram-table(list((word1) (word2)) readword in))) 
  (hash-set! Ngram-table(append((cdr data) word1)) readword in) 

どうやら in の後の readword は、これが出力などではなく入力であることをコンピューターに伝えることになっているようです。

ハッシュテーブルのキーのデータをこのようにオーバーラップさせるには、これをどのように呼び出しますか? そして、再帰呼び出しはどのように見えるでしょうか?

編集: また、このプログラムで割り当てステートメントを使用することは許可されていません。

4

1 に答える 1

0

readword最初に、テストのために、リストから連続する単語を返すプロシージャを定義します。(この場合、これは単なる数字のリストですが、それほど重要ではありません。) これらの 1 つを既に取得していますが、残りのコードを機能させるには 1 つ必要です。これは割り当て ( ) を使用していますが、これは実際に記述する必要があるコードset!ではありません。これは、この回答の残りの部分を機能させるためのものです。

(define words (list 1 2 3 4 5 6))

(define (readword)
  (cond 
    ((null? words) words)
    (else (let ((word (car words)))
            (set! words (cdr words))
            word))))
> (readword)
1
> (readword)
2

readwordこれで、ハッシュ テーブルを作成し、 を使用して入力し、返す main 関数を定義できます。insert-wordsには、2 つの単語が既に読み取られていると想定する内部ヘルパー関数があるため、次の単語を読み取るだけで済みます。私たちのreadword関数は()、読み取る単語がなくなると戻ります。そのため、ヘルパー関数は戻り時に停止し、単純に を返しreadwordます。それ以外の場合は単語を返し、 as in でハッシュテーブルにエントリを追加できます。その後、ヘルパー関数を再度呼び出しますが、3 番目の単語が必要な前の 2 つの単語としてandを使用します。()ngramsreadwordhash-set!(hash-set! ngrams (list w1 w2) w3)w2w3

(define (insert-words)
  (define (insert-helper ngrams w1 w2)
    (let ((w3 (readword)))
      (cond
        ((null? w3) ngrams)
        (else 
         (hash-set! ngrams (list w1 w2) w3)
         (insert-helper ngrams w2 w3)))))
  (insert-helper (make-hash) (readword) (readword)))
> (insert-words)
'#hash(((1 2) . 3) ((3 4) . 5) ((4 5) . 6) ((2 3) . 4))

反復を実行するヘルパー関数を使用したこの種のパターンは非常に一般的であるため、Scheme と Racket は名前付き letと呼ばれるものをサポートしています。名前付き let を使用すると、次のようになります。これは本質的にループであるため、名前を使用しましたloopが、特定の名前は問題ではありません。

(define (insert-words)
  (let loop ((ngrams (make-hash))
             (w1 (readword))
             (w2 (readword)))
    (let ((w3 (readword)))
      (cond
        ((null? w3) ngrams)
        (else 
         (hash-set! ngrams (list w1 w2) w3)
         (loop ngrams w2 w3))))))
于 2013-11-07T03:53:06.323 に答える