Skip to content

Commit

Permalink
Refactored, added unit tests and removed opIndex.
Browse files Browse the repository at this point in the history
Moved checks for which Range is longer to levenshteinDistance() method.

Reverted to implementation found in original distance() with regards to
using front/popFront instead of opIndex.

Fixed formatting of return statement.

Added two unit tests for levenshteinDistance().

Credit to @Poita.
  • Loading branch information
JamesDavidCarr committed Jul 13, 2014
1 parent a9ae102 commit 0d0a2c0
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions std/algorithm.d
Expand Up @@ -7603,28 +7603,25 @@ struct Levenshtein(Range, alias equals, CostType = size_t)

CostType distance(Range s, Range t)
{
if (s.length > t.length)
{
auto swap = s.idup;
s = t;
t = swap;
}

auto slen = walkLength(s.save), tlen = walkLength(t.save);
CostType lastdiag, olddiag;
AllocMatrix(slen + 1,1);
AllocMatrix(slen + 1, 1);
foreach (y; 1 .. slen + 1)
{
matrix(y,0) = y;
}
foreach (x; 1 .. tlen + 1)
{
auto tfront = t.front;
t.popFront();
auto ss = s;
matrix(0,0) = x;
lastdiag = x - 1;
foreach (y; 1 .. rows)
{
olddiag = matrix(0,y);
auto cSub = lastdiag + (equals(s[y-1], t[x-1]) ? 0 : _substitutionIncrement);
auto cSub = lastdiag + (equals(ss.front, tfront) ? 0 : _substitutionIncrement);
ss.popFront();
auto cIns = matrix(0,y - 1) + _insertionIncrement;
auto cDel = matrix(0,y) + _deletionIncrement;
switch (min_index(cSub, cIns, cDel))
Expand All @@ -7642,7 +7639,7 @@ struct Levenshtein(Range, alias equals, CostType = size_t)
lastdiag = olddiag;
}
}
return(matrix(0,slen));
return matrix(0,slen);
}

EditOp[] path(Range s, Range t)
Expand Down Expand Up @@ -7771,7 +7768,14 @@ size_t levenshteinDistance(alias equals = "a == b", Range1, Range2)
if (isForwardRange!(Range1) && isForwardRange!(Range2))
{
Levenshtein!(Range1, binaryFun!(equals), size_t) lev;
return lev.distance(s, t);
if (walkLength(s.save) > walkLength(t.save))
{
return lev.distance(s, t);
}
else
{
return lev.distance(t, s);
}
}

///
Expand All @@ -7784,6 +7788,8 @@ unittest
assert(levenshteinDistance("kitten", "sitting") == 3);
assert(levenshteinDistance!((a, b) => std.uni.toUpper(a) == std.uni.toUpper(b))
("parks", "SPARK") == 2);
assert(levenshteinDistance("parks".filter!"true", "spark".filter!"true") == 2);
assert(levenshteinDistance("ID", "I♥D") == 1);
}

/**
Expand Down

0 comments on commit 0d0a2c0

Please sign in to comment.