performance - 如何在 Haskell 中记忆 LCS
问题描述
作为修改我的算法知识的一部分,我决定用 Java 实现最长公共子序列问题,然后用我最喜欢的新语言——Haskell。
lcs :: (Eq a) => [a] -> [a] -> [a]
lcs [] _ = []
lcs _ [] = []
lcs (x:xs) (y:ys) =
if (x == y) then x : lcs xs ys
else longer (lcs xs (y:ys), lcs (x:xs) ys)
where longer (a, b) = if (length a > length b) then a else b
我对 Haskell 的满意之处在于,与命令式语言相比,对算法进行编码既可以让您更多地理解算法,又可以编写更简洁的代码。但是,此代码严重依赖于利用递归调用,从而形成了大量的调用二叉树。这使它成为记忆的完美候选者。
问题是我无法真正说出如何实现这一目标。对我来说,与我的命令式思维产生共鸣的自然选择是创建一个带有第三个参数的辅助函数作为缓存,它是从 ([Char], [Char]) 到 [Char] 的 Map 并检查 ( member
?)函数的每次递归调用。并根据结果从地图中返回值或插入要计算的内容。
再说一次,这似乎是一种编写 Haskell 代码的不纯粹方式,因为这基本上意味着模拟状态和副作用。更糟糕的是,这会将以前优雅的解决方案与地图上的操作结合起来。那么处理这个问题的正确方法是什么?
解决方案
推荐阅读
- laravel - 如何让 Laravel 写一个日志来显示我的问题?
- python - 修复“ImportError:无法导入名称 message_decoder”的问题 python nfcpy ndef
- java - 如何通过 xpath 查找具有相同类、名称等的元素
- python - 硒不阻塞元素
- javascript - Vue Froala 动态配置选项
- makefile - Makefile - 根据条件分配变量
- xamarin.forms - 使用 MVVM 的主详细信息页面
- node.js - 在节点 postgres 中一次插入多行
- django - 动态添加表单集的字段
- c# - wpf c# datagrid GroupStyle - 扩展哪些行