我必须编写一个Scheme谓词来计算定义为的函数f(N - > N):
我编写了一个有效的简单谓词:
(define functionfNaive
(lambda (n)
(if (< n 4) (+ (* n n) 5)
(* (+ (functionfNaive (- n 1)) (functionfNaive (- n 2)))
(functionfNaive (- n 4))))))
现在,我尝试使用累加器的方法,但它不起作用...... 我的代码:
(define functionf
(lambda(n)
(functionfAux n 5 9 14)))
(define functionfAux
(lambda (n n1 n2 n4)
(cond
[(< n 4) (+ (* n n) 5)]
[(= n 4) (* n1 (+ n2 n4))]
[else (functionfAux (- n 1) n2 n4 (* n1 (+ n2 n4)))])))
答案 0 :(得分:4)
根据要求,这是一个代码的备忘版本,其性能优于天真版本:
(define functionf
(let ((cache (make-hash)))
(lambda (n)
(hash-ref!
cache
n
(thunk
(if (< n 4)
(+ (* n n) 5)
(* (+ (functionf (- n 1)) (functionf (- n 2))) (functionf (- n 4)))))))))
BTW ...计算大n
值的结果非常快,但打印需要花费很多时间。要测量时间,请使用
(time (functionf 50) 'done)
这是一个通用的memoize程序,如果你需要它:
(define (memoize fn)
(let ((cache (make-hash)))
(λ arg (hash-ref! cache arg (thunk (apply fn arg))))))
在您的情况下可以像
一样使用(define functionf
(memoize
(lambda (n)
(if (< n 4)
(+ (* n n) 5)
(* (+ (functionf (- n 1)) (functionf (- n 2))) (functionf (- n 4)))))))
答案 1 :(得分:1)
首先,那不是谓词。 Predicate是一个返回布尔值的函数。
要计算 n 结果,请从前四个开始计算,并保持最后四个已知元素。到达 n 时停止:
(define (step a b c d n)
(list b c d (* (+ c d) a)) (+ n 1)))
等。简单。第一个电话会是(step 5 6 9 14 3)
。
答案 2 :(得分:1)
递归树的深度可能是最大的问题,因此可能使用迭代,这意味着使用一些变量来记忆中间过程。
#lang racket
(define (functionf n)
(define (iter now n1 n2 n3 n4 back)
(if (= n now)
back
(iter (+ now 1) back n1 n2 n3 (* n3 (+ back n1)))))
(if (< n 4)
(+ 5 (* n n))
(iter 4 14 9 6 5 125)))
(functionf 5)
这样,堆栈的深度只有1,代码加速了。