在Racket中编写缓存函数

时间:2011-11-11 04:26:09

标签: functional-programming lisp scheme racket memoization

所以我正在研究一些代码(参加关于Racket课程的练习考试),我必须做以下事情:

编写一个函数cached-assoc,它接受​​一个列表xs和一个数字n并返回一个带有一个参数v的函数并返回相同的函数assoc v xs 1}})会回来。

你应该使用最近结果的n元素缓存来使这个函数更快,而不仅仅是调用assoc。缓存应该是长度为n的向量,每次调用cached-assoc返回的函数时,都会通过调用cached-assoc和used-and-possible-mutated来创建长度为n的向量。

缓存开始为空(所有元素都是#f)。当调用cached-assoc返回的函数时,它首先检查缓存中的答案。如果不存在,则使用assocxs来获取答案,如果结果不是#f(即xs有一对匹配),则将对添加到返回之前的缓存 (使用矢量集!)。

缓存插槽以循环方式使用:第一次将一对添加到缓存中时,它将放在位置0中,下一对放在位置1,等等到位置n - 1然后返回位置0(替换已存在的位置),然后定位1等。

我不知道该怎么做。

2 个答案:

答案 0 :(得分:4)

这个问题需要你做一些事情。以下是部分列表:

  1. 如何构建具有内部非全局状态的函数。
  2. 如何定义可以在向量中搜索项目的函数。
  3. 如何构造一个充当另一个函数的函数的函数。
  4. 知道 assoc 的作用。
  5. 如何改变矢量。
  6. 如何改变局部变量。
  7. 作为一个测验问题,它实际上是在同时运用几个概念,如果你没有冷却这些概念,你将会遇到困难。

    这些问题确实存在问题,还是其他让你陷入困境的问题?

答案 1 :(得分:2)

这是我的实施。这只是为了让您了解如何解决这个问题;我写的方式可能不会通过作业提交(不是我认为这是你的意图)。 : - )

(define (cached-assoc xs n)
  (define cache (make-vector n #f))
  (define index 0)
  (define (fetch-cache k i)
    (if (or (negative? i) (< i (- index n))) #f
        (let ((cur (vector-ref cache (modulo i n))))
          (if (equal? (car cur) k) cur
              (fetch-cache k (sub1 i))))))
  (define (update-cache val)
    (vector-set! cache (modulo index n) val)
    (set! index (add1 index))
    val)
  (lambda (k)
    (cond ((fetch-cache k (sub1 index)))
          ((assoc k xs) => update-cache)
          (else #f))))