在递归函数中进行记忆
使用前面计算整数的阶乘的示例,在散列表中放入在递归内计算的所有阶乘的值,这些值不会出现在表中。
由于有关的文章在记忆化 ,我们定义一个函数 f
接受一个函数参数 fact
和整数参数。此函数 f
包含从 fact(n-1)
计算 n
的阶乘的指令。
这允许通过 memorec
而不是 fact
本身返回的函数来处理递归,并且如果 fact(n-1)
值已经被计算并且位于散列表中,则可能停止计算。
let memorec f =
let cache = Dictionary<_,_>()
let rec frec n =
let value = ref 0
let exist = cache.TryGetValue(n, value)
match exist with
| true ->
printfn "%O -> In cache" n
| false ->
printfn "%O -> Not in cache, calling function..." n
value := f frec n
cache.Add(n, !value)
!value
in frec
let f = fun fact n -> if n<2 then 1 else n*fact(n-1)
[<EntryPoint>]
let main argv =
let g = memorec(f)
printfn "%A" (g 10)
printfn "%A" "---------------------"
printfn "%A" (g 5)
Console.ReadLine()
0
结果:
10 -> Not in cache, calling function...
9 -> Not in cache, calling function...
8 -> Not in cache, calling function...
7 -> Not in cache, calling function...
6 -> Not in cache, calling function...
5 -> Not in cache, calling function...
4 -> Not in cache, calling function...
3 -> Not in cache, calling function...
2 -> Not in cache, calling function...
1 -> Not in cache, calling function...
3628800
"---------------------"
5 -> In cache
120