【发布时间】:2019-02-04 20:16:32
【问题描述】:
这行得通:
f :: Int -> Int
f n = gof n where
gof 0 = 1
gof i = i - ms!! ( fs!! (i-1) )
gom 0 = 0
gom i = i - fs!! ( ms!! (i-1) )
fs = [gof j | j <- [0..n]]
ms = [gom j | j <- [0..n]]
m n = gom n where
gof 0 = 1
gof i = i - ms!! ( fs!! (i-1) )
gom 0 = 0
gom i = i - fs!! ( ms!! (i-1) )
fs = [gof j | j <- [0..n]]
ms = [gom j | j <- [0..n]]
但是它确实是重复的。有没有办法避免重复这些代码块?一些参考资料,这是改编自:
http://jelv.is/blog/Lazy-Dynamic-Programming/
序列参考:
https://en.wikipedia.org/wiki/Hofstadter_sequence
我核对了数字:
https://oeis.org/A005378 https://oeis.org/A005379
它生成正确的数字,并且比基本代码快得多,基本代码在开始出现递归深度问题之前根本不会太高。
【问题讨论】:
-
好吧,您当然可以共享
m和f之间的所有子定义。这对序列看起来你可以做得更好,并以核心递归方式生成它们。 -
请注意,列表上的
!!效率低下,因为它的成本为 O(n)。如果无法避免索引,请考虑使用一些 O(1) 数据结构,例如数组。递归深度也不应该是一个问题,除非它真的很大——你为什么要提到这个? (你用的不是古代的拥抱,对吧?)
标签: haskell recursion memoization