假设我想要实现通常用于Levensthein距离(编辑距离)的动态规划算法。很容易想到递归:
editDistance [] ys = length ys
editDistance xs [] = length xs
editDistance (x:xs) (y:ys)
| x == y = editDistance xs ys
| otherwise = minimum [
1 + editDistance xs (y:ys),
1 + editDistance (x:xs) ys,
1 + editDistance xs ys]
这个函数的运行时间呈指数级增长,因此有必要进行记忆化处理。我想使用Data.Memocombinators来实现,已经尝试了几种方法。以下是我的当前尝试:
import qualified Data.MemoCombinators as M
memLength str =
M.wrap
(\i -> drop i str)
(\xs -> length str - length xs)
(M.arrayRange (0,length str))
elm xs ys = (M.memo2 memListx memListy editDistance) xs ys
where
memListx = memLength xs
memListy = memLength ys
然而,备忘录似乎没有任何作用,尽管我期望任何备忘录都会显着提高运行时间,因为它至少是多项式的。我的实现有什么问题?如何在尽可能保留编辑距离高级定义的同时获得良好的运行时间?