这是 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 实现方式?