haskell - 为什么这个 memoized 的 Pascal 三角递归没有预期的那么快?

标签 haskell memoization pascals-triangle

Memoization 上引用这篇文章,我相信这种方法使用内存,应该很快。然而,这里似乎并非如此:

pascal :: Int -> Int -> Integer
pascal a = (map ((map pascal' [0..]) !! a) [0..] !!)
  where pascal' a b | a == 1 && b == 1  = 1
                    | a <= 0 || b <= 0  = 0 
                    | otherwise         = pascal (a-1) (b-1) + pascal (a-1) b 

Haskell 如何解释这个?如何让这个功能更快?

最佳答案

您需要将(完整)数据结构的构建与数据结构中正确元素的选择分开。

也就是说,你需要定义整个帕斯卡三角形:

triangle :: [[Integer]]
triangle = [[pascal' a b | b <- [0..]] | a <- [0..]]
  where pascal' a b | a == 1 && b == 1  = 1
                    | a <= 0 || b <= 0  = 0
                    | otherwise         = triangle !! (a-1) !! (b-1) 
                                          + triangle !! (a-1) !! b

然后从三角形中选择的内容将被内存:

> triangle !! 100 !! 50
50445672272782096667406248628
>

定义数据结构并命名后,您可以定义访问元素的函数:

pascal :: Int -> Int -> Integer
pascal a b = triangle !! a !! b

调用电话:

> pascal 100 50
50445672272782096667406248628

可以将triangle移到where子句中,给出完整代码:

pascal :: Int -> Int -> Integer
pascal a b = triangle !! a !! b
  where
    triangle = [[pascal' a b | b <- [0..]] | a <- [0..]]
    pascal' a b | a == 1 && b == 1  = 1
                | a <= 0 || b <= 0  = 0
                | otherwise         = triangle !! (a-1) !! (b-1)
                                      + triangle !! (a-1) !! b

即使未优化编译或加载到 GHCi 中,它也应该可以正常工作。

关于haskell - 为什么这个 memoized 的 Pascal 三角递归没有预期的那么快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72142433/

相关文章:

haskell - 分而治之算法的并行性

haskell - Haskell 中的记忆化和 Project Euler Problem 15

java - 帕斯卡三角形定位

java - 将一段 Java 代码翻译为 Haskell

haskell - 将 Coq 提取到 Haskell

使用记忆化/动态编程的 Java 组合学

common-lisp - 通过Lisp地带的封闭示例进行内存

c - C 语言中的帕斯卡三角形及其组合

c - C 奇怪输出中的帕斯卡三角形

algorithm - 我的排序算法不起作用