【发布时间】:2021-09-08 18:37:24
【问题描述】:
这是 Curry 中的一个算法,它采用 n 并匹配编辑距离 n 内的两个字符串。
lev :: Eq a => Int -> [a] -> [a] -> ()
lev n (a : b) (a : c) =
lev n b c
lev n (_ : b) (_ : c) | n > 0 =
lev (n - 1) b c
lev n (_ : b) c | n > 0 =
lev (n - 1) b c
lev n b (_ : c) | n > 0 =
lev (n - 1) b c
lev n [] [] =
()
这会修改朴素的递归算法,从而限制我们可以尝试的编辑次数。一旦我们尝试n 编辑,我们就会放弃。
如果我们把它翻译成 Prolog,我们会得到
p(_, [], []).
p(N, [A|B], [A|C]) :-
p(N, B, C).
p(N, [_|B], C) :-
N>0,
p(N-1, B, C).
p(N, B, [_|C]) :-
N>0,
p(N-1, B, C).
p(N, [_|B], [_|C]) :-
N>0,
p(N-1, B, C).
虽然这些确实限制了他们可以尝试的编辑次数,但分支因子没有限制。因此,它具有相对于输入大小的指数运行时间。在 Prolog 中,我可以通过剪切来解决这个问题:
p(_, [], []).
p(N, [A|B], [A|C]) :-
!, p(N, B, C).
p(N, [_|B], C) :-
N>0,
p(N-1, B, C).
p(N, B, [_|C]) :-
N>0,
p(N-1, B, C).
p(N, [_|B], [_|C]) :-
N>0,
p(N-1, B, C).
现在分支因子已设置上限,并且在线性时间内运行。但是我不能对库里做出同样的改变,因为库里没有削减。
实现这一点的惯用 Curry 方式是什么?
【问题讨论】:
标签: performance prolog logic-programming curry