在球拍中使用哈希表

时间:2013-11-07 03:17:38

标签: scheme hashtable racket

我在Ngrams程序上工作,我无法填写我的哈希表。 我想写出一个递归函数,它将获取单词并将它们添加到哈希表中。它应该工作的方式给出数据集1 2 3 4 5 6 7 哈希表中的第一个条目应该有一个键 [1 2],数据应为3。 第二个条目应该是: [2 3]及其数据应为4  并一直持续到文本文件结束。

我们给出了一个名为readword的预定义函数,它只返回文本中的1个单词。但我不知道如何使这些呼叫相互重叠。如果数据是硬编码的话,调用看起来会像这样。

(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) 
显然,readword之后的内容应该告诉计算机 这是输入而不是输出或类似的东西。

我如何调用它来使哈希表的键中的数据像这样重叠? 递归调用会是什么样的?

编辑:我们也不允许在此程序中使用分配语句。

1 个答案:

答案 0 :(得分:0)

首先,为了测试,我们将定义一个readword过程,它返回列表中的连续单词。 (在这种情况下,它只是一个数字列表,但这并不重要。)你已经有了其中一个,但我们需要一个让代码的 rest 工作。这使用了一个赋值(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定义创建,填充的主函数,并返回一个哈希表。 insert-words有一个内部辅助函数,假设已经读取了两个单词,因此它只需要读取下一个单词。当没有更多单词需要读取时,我们的readword函数会返回(),因此当readword返回()并返回ngrams时,我们的辅助函数会停止。否则,readword会返回一个字词,我们可以在(hash-set! ngrams (list w1 w2) w3)中使用hash-set!向哈希表添加条目。之后,我们再次调用辅助函数,但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))))))