0

我正在开发一个 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) 

显然 in after readword 应该告诉计算机这是输入而不是输出或类似的东西。

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

编辑:我们也不允许在这个程序中使用赋值语句。

4

1 回答 1

0

首先,为了测试,我们将定义一个readword从列表中返回连续单词的过程。(在这种情况下,它只是一个数字列表,但这并不重要。)您已经拥有其中一个,但我们需要一个来使其余代码工作。这使用了一个赋值 ( 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函数返回,所以我们的辅助函数在返回时停止并简单地返回。否则,返回一个单词,我们可以使用as 在哈希表中添加一个条目。之后,我们再次调用辅助函数,但使用and作为前两个单词,需要第三个单词。()readword()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,如下所示。我使用了 name 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 回答