Hash Scheme-如何在遍历字符串时查找字符索引

Hash Scheme-如何在遍历字符串时查找字符索引,hash,scheme,lambda,Hash,Scheme,Lambda,我在Scheme中编写的函数有问题。该方法将表示为符号列表的单词作为输入,并对每个字符执行哈希方程并返回一个值。最终值是集合中每个字符的哈希值之和 将字符串想象为一个字符数组“w”,其中w[i]是数组中每个字符的索引 该公式是单词中每个字符-->7^i*ctv(w[i])的总和 对于ctv(“字符到值”)将“a”映射到1,“b”映射到2的每个字母。。。z到26 例如,key(“day”) =(7^0*ctv('d'))+(7^1 ctv('a'))+(7^2 ctv('y'))=1236 所以,

我在Scheme中编写的函数有问题。该方法将表示为符号列表的单词作为输入,并对每个字符执行哈希方程并返回一个值。最终值是集合中每个字符的哈希值之和

将字符串想象为一个字符数组“w”,其中w[i]是数组中每个字符的索引

该公式是单词中每个字符-->7^i*ctv(w[i])的总和

对于ctv(“字符到值”)将“a”映射到1,“b”映射到2的每个字母。。。z到26

例如,key(“day”) =(7^0*ctv('d'))+(7^1 ctv('a'))+(7^2 ctv('y'))=1236

所以,我的实际问题是如何找到索引,单词中每个字符的w[I]中的I。 这是我的第一个想法,使用(长度w)作为索引,但我知道这是不正确的

(define keys
  (lambda(w)
    (if(null? w)
      0
    (+ (* (ctv(car w)) (expt 7 (length w)))  (keys (cdr w)))))
   )
我的下一个想法是也许它的尺寸是兰姆达,就像这样。 注-我知道需要将其更改为(1号)

但即使如此,大小仍然是索引的另一端,例如,对于“day”,大小-1表示“d”为2,大小-1表示“y”为0


无论如何,如果有人知道我在说什么,并且有可能的解决方案或建议,请回复

这里的技巧是将索引作为参数传递,并在遍历列表的同时增加它。此外,如果我们将输入字符串转换为字符列表,则更容易,例如:

(define (key word)
  (let loop ((chars (string->list word)) ; list of chars
             (idx 0)  ; current index
             (acc 0)) ; accumulated result
    (if (null? chars) ; if the list is empty
        acc           ; return the accumulator
        (loop (cdr chars) ; otherwise go to the next char
              (add1 idx)  ; advance the index
              (+ acc (* (expt 7 idx) (ctv (car chars)))))))) ; compute result
假设
ctv
程序正确执行,它应按预期工作:

(key "day")
=> 1236

由于此问题也被标记为“球拍”,您可能会欣赏一个优雅的、仅限于球拍的解决方案,使用和:

测试:

> (key "day")
1236

获取以下错误:字符串->列表:需要类型为的参数;给定(HE l o)。测试程序的单词以前是这样定义的:(define hello’(hel l l o)),因此我可以在hello上运行“keys”。因此,所有单词都需要表示为一组符号。最后一行的乘法部分也会出现此错误:*:需要类型作为第二个参数,给定:#;其他论点包括:1@RCouch对于第一个错误:在您的问题中,您说输入看起来像
“day”
,请使用应该用作输入的实际值更新问题。对于第二个错误:这是因为在您的
ctv
实现中有一个错误,当前它返回
#
,您必须修复它并正确地测试它才能使此算法工作。@r顺便说一句:使用符号列表解决此问题是一个非常麻烦的问题,您的算法需要字符,而不是符号,如果你只使用一个字符串作为输入,就会简单得多,就像你在当前问题中删除了球拍标签。。。事实上,它需要在计划中,而不是喧闹。
(define (key word)
  (for/sum (((c i) (in-indexed word)))
    (* (expt 7 i) (cvt c))))
> (key "day")
1236