我正在尝试在Scheme中创建一个通用的memoization过程。这就是我到目前为止(它与SICP书中的练习3.27几乎完全相同):
(define (memo proc)
(let ((table (make-table)))
(lambda (args)
(let ((prev (lookup args table)))
(or prev
(let ((result (proc args)))
(insert! args result table)
result))))))
(' make-table','插入!'以及'查找'程序在SICP书籍中定义)
如果我用一个只带一个参数的过程调用这个方法,它就可以了。我无法弄清楚如何使用一个带有0个或多个参数的过程。
我找到了这个链接:http://community.schemewiki.org/?memoization,但我还是无法让它发挥作用。链接中的过程使用应用值和值调用,即使我对它们的工作方式有了大致的了解,但我似乎无法将其与我的过程集成。
(define (mem2 proc)
(let ((table (make-table)))
(lambda args
(let ((prev (lookup args table)))
(or prev
(call-with-values
(lambda () (apply proc args))
(lambda (result)
(insert! args result table)
result)))))))
这是我尝试使用列表从链接开始的过程。它几乎可以正常工作,但是如果我有一个带有多个参数的过程,它会多次计算它。让我们说我通过一个随机程序参数1 2 3 4.它将在表中保存1 2 3 4,但不会分别给出1,2,3和4的给定结果。我想我的错误是我查找的地方,因为我立刻传递了整个列表。
编辑:添加了mem2无法正常使用的testprocedure。
(define (add . args)
(display "computing add of ")
(display args) (newline)
(if (null? args)
0
(+ (car args) (apply add (cdr args)))))
它将在查询表中保存整个' args'。如果我有:
(定义add(mem2 add))
(加2 3 4)
计算添加(2 3 4)
计算添加(3 4)
计算添加(4)
9
(加3)
计算添加(3)
答案 0 :(得分:1)
(define (make-table)
(vector '()))
(define (insert! key val t)
(vector-set! t 0 (cons (cons key val) (vector-ref t 0))))
(define (lookup key t)
(let ([result (assoc key (vector-ref t 0))])
(and result (cdr result))))
(define (mem2 proc)
(let ((table (make-table)))
(lambda args
(let ((prev (lookup args table)))
(or prev
(let ([result (apply proc args)])
(insert! args result table)
result))))))
(define (plus x y)
(display (list "Computing sum of: " x y))
(newline)
(+ 1 2))
(define memo-plus (mem2 plus))
(memo-plus 1 2)
(memo-plus 1 2)
输出:
(Computing sum of: 1 2)
3
3
添加:
(define (add . args)
(display "computing add of ")
(display args) (newline)
(if (null? args)
0
(+ (car args) (apply add (cdr args)))))
(define memo-add (mem2 add))
(memo-add 1 2 3 4)
(memo-add 1 2 3 4)
给出输出:
computing add of (1 2 3 4)
computing add of (2 3 4)
computing add of (3 4)
computing add of (4)
computing add of ()
10
10
因为在最后10个之前没有打印过这个例子 表明结果已被记忆。