Scheme 在racket中使用哈希表

Scheme 在racket中使用哈希表,scheme,hashtable,racket,Scheme,Hashtable,Racket,我正在做一个Ngrams程序,我在填写哈希表时遇到了麻烦。 我想写一个递归函数,它将接受这些单词并将它们添加到哈希表中。数据集1234567给出了它的工作方式 哈希表中的第一个条目的键应为 [1 2]数据应为3。 第二项应为: [2 3]其数据应为4 并继续,直到文本文件结束 我们得到了一个名为readword的预定义函数,它只需从文本中返回一个单词。但我不知道如何让这些电话互相重叠。如果数据是硬编码的,调用看起来会像这样 (hash-set! (list "1" "2") 3 (hash-s

我正在做一个Ngrams程序,我在填写哈希表时遇到了麻烦。 我想写一个递归函数,它将接受这些单词并将它们添加到哈希表中。数据集1234567给出了它的工作方式 哈希表中的第一个条目的键应为 [1 2]数据应为3。 第二项应为: [2 3]其数据应为4 并继续,直到文本文件结束

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

(hash-set! (list "1" "2") 3 
(hash-set! (list "2" "3") 4
我试过的两个电话是这样的

  (hash-set! Ngram-table(list((word1) (word2)) readword in))) 
  (hash-set! Ngram-table(append((cdr data) word1)) readword in) 
显然,读入后的单词应该告诉计算机 这是输入,而不是输出或类似的东西

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


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

首先,为了测试,我们将定义一个
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
创建、填充并返回哈希表
insert words
有一个内部帮助函数,该函数假定已经读取了两个单词,因此它只需要读取下一个单词。我们的
readword
函数在没有更多的字可读时返回
()
,因此我们的助手函数在
readword
返回
()
时停止,只返回
ngrams
。否则,
readword
返回一个单词,我们可以使用
(hash set!ngrams(list w1 w2)w3)
向哈希表添加一个条目。在那之后,我们再次调用helper函数,但是前面两个单词需要使用
w2
w3

(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)))
这种带有执行迭代的辅助函数的模式非常常见,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))))))

你打那些电话时发生了什么?你收到错误消息了吗?它是什么?不是
散列集赋值语句?毕竟,它是给哈希表中的一个条目赋值。我还没有做到这一点,因为我不确定如何使用哈希表。我理解对哈希表的调用是如何工作的,这不是问题所在。我的问题是如何准确地调用哈希表以使其正确分配数据。你不调用哈希表,而是调用
哈希集,它将哈希表作为参数。它在球拍文档中。它的签名是
(hash set!hash key v)
,正如我在回答中所描述的。
> (insert-words)
'#hash(((1 2) . 3) ((3 4) . 5) ((4 5) . 6) ((2 3) . 4))
(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))))))