mirror of
https://github.com/dlang/phobos.git
synced 2025-05-04 09:00:22 +03:00
Refactored, added unit tests and removed opIndex.
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.
This commit is contained in:
parent
a9ae1023a2
commit
0d0a2c0308
1 changed files with 17 additions and 11 deletions
|
@ -7603,13 +7603,6 @@ struct Levenshtein(Range, alias equals, CostType = size_t)
|
||||||
|
|
||||||
CostType distance(Range s, Range 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);
|
auto slen = walkLength(s.save), tlen = walkLength(t.save);
|
||||||
CostType lastdiag, olddiag;
|
CostType lastdiag, olddiag;
|
||||||
AllocMatrix(slen + 1, 1);
|
AllocMatrix(slen + 1, 1);
|
||||||
|
@ -7619,12 +7612,16 @@ struct Levenshtein(Range, alias equals, CostType = size_t)
|
||||||
}
|
}
|
||||||
foreach (x; 1 .. tlen + 1)
|
foreach (x; 1 .. tlen + 1)
|
||||||
{
|
{
|
||||||
|
auto tfront = t.front;
|
||||||
|
t.popFront();
|
||||||
|
auto ss = s;
|
||||||
matrix(0,0) = x;
|
matrix(0,0) = x;
|
||||||
lastdiag = x - 1;
|
lastdiag = x - 1;
|
||||||
foreach (y; 1 .. rows)
|
foreach (y; 1 .. rows)
|
||||||
{
|
{
|
||||||
olddiag = matrix(0,y);
|
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 cIns = matrix(0,y - 1) + _insertionIncrement;
|
||||||
auto cDel = matrix(0,y) + _deletionIncrement;
|
auto cDel = matrix(0,y) + _deletionIncrement;
|
||||||
switch (min_index(cSub, cIns, cDel))
|
switch (min_index(cSub, cIns, cDel))
|
||||||
|
@ -7642,7 +7639,7 @@ struct Levenshtein(Range, alias equals, CostType = size_t)
|
||||||
lastdiag = olddiag;
|
lastdiag = olddiag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(matrix(0,slen));
|
return matrix(0,slen);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditOp[] path(Range s, Range t)
|
EditOp[] path(Range s, Range t)
|
||||||
|
@ -7771,8 +7768,15 @@ size_t levenshteinDistance(alias equals = "a == b", Range1, Range2)
|
||||||
if (isForwardRange!(Range1) && isForwardRange!(Range2))
|
if (isForwardRange!(Range1) && isForwardRange!(Range2))
|
||||||
{
|
{
|
||||||
Levenshtein!(Range1, binaryFun!(equals), size_t) lev;
|
Levenshtein!(Range1, binaryFun!(equals), size_t) lev;
|
||||||
|
if (walkLength(s.save) > walkLength(t.save))
|
||||||
|
{
|
||||||
return lev.distance(s, t);
|
return lev.distance(s, t);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return lev.distance(t, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
unittest
|
unittest
|
||||||
|
@ -7784,6 +7788,8 @@ unittest
|
||||||
assert(levenshteinDistance("kitten", "sitting") == 3);
|
assert(levenshteinDistance("kitten", "sitting") == 3);
|
||||||
assert(levenshteinDistance!((a, b) => std.uni.toUpper(a) == std.uni.toUpper(b))
|
assert(levenshteinDistance!((a, b) => std.uni.toUpper(a) == std.uni.toUpper(b))
|
||||||
("parks", "SPARK") == 2);
|
("parks", "SPARK") == 2);
|
||||||
|
assert(levenshteinDistance("parks".filter!"true", "spark".filter!"true") == 2);
|
||||||
|
assert(levenshteinDistance("ID", "I♥D") == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue