patternMinor
Levenshtein Distance with Haskell Vectors and Memoization
Viewed 0 times
vectorsmemoizationwithdistancelevenshteinhaskelland
Problem
Is the following an effective way to implement the Levenshtein Distance with Haskell vectors?
In particular, should I be using
import qualified Data.Vector as V
levenshtein s1 s2 = levenshteinV (V.fromList s1) (V.fromList s2)
levenshteinV p1 p2 = lev V.! l1 V.! l2
where
lev = V.map levi (V.enumFromN 0 (l1 + 1))
levi i = V.map (levij i) (V.enumFromN 0 (l2 + 1))
levij i j
| i == 0 = j
| j == 0 = i
| otherwise =
((lev V.! (i - 1) V.! j) + 1) `min`
((lev V.! i V.! (j - 1)) + 1) `min`
((lev V.! (i - 1) V.! (j - 1)) + ind (i - 1) (j - 1))
ind i j = if p1 V.! i == p2 V.! j then 0 else 1
l1 = V.length p1
l2 = V.length p2In particular, should I be using
V.map to construct the vectors or is there a better approach? Perhaps V.generate? Or does it not make a difference because of lazy evaluation?Solution
Readability improves a lot with
If you like point-free notation, you can short-cut levi, with intermediate manual steps:
2
3
4
Your code looks good. You might try it with
import Data.Vector ((!)) and replacing V.! with !.generate looks better; performance-wise I do not expect a difference (with optimization).lev = V.generate (l1 + 1) leviIf you like point-free notation, you can short-cut levi, with intermediate manual steps:
lev = V.generate (l1 + 1) levi
levi i = V.generate (l2 + 1) (levij i)2
lev = V.generate (l1 + 1) (\i ->
V.generate (l2 + 1) (levij i))3
lev = V.generate (l1 + 1) (\i -> V.generate (l2 + 1) (levij i))4
lev = V.generate (l1 + 1) (V.generate (l2 + 1) . levij)Your code looks good. You might try it with
Array next, to two-dimensional Index. The google results for haskell levenshtein Array are only marginally better than your Vector approach.Code Snippets
lev = V.generate (l1 + 1) levilev = V.generate (l1 + 1) levi
levi i = V.generate (l2 + 1) (levij i)lev = V.generate (l1 + 1) (\i ->
V.generate (l2 + 1) (levij i))lev = V.generate (l1 + 1) (\i -> V.generate (l2 + 1) (levij i))lev = V.generate (l1 + 1) (V.generate (l2 + 1) . levij)Context
StackExchange Code Review Q#87438, answer score: 2
Revisions (0)
No revisions yet.