|
@@ -19,7 +19,7 @@
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
#include <algorithm>
|
|
|
#include <utility>
|
|
#include <utility>
|
|
|
-#include <deque>
|
|
|
|
|
|
|
+#include <set>
|
|
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
|
class LevenshteinPotencial
|
|
class LevenshteinPotencial
|
|
@@ -64,21 +64,21 @@ template <class T, typename SIZE=unsigned int>
|
|
|
unsigned int levenshtein(const T &a, const T &b, const SIZE aSize, const SIZE bSize)
|
|
unsigned int levenshtein(const T &a, const T &b, const SIZE aSize, const SIZE bSize)
|
|
|
{
|
|
{
|
|
|
int **items = new int*[aSize]();
|
|
int **items = new int*[aSize]();
|
|
|
- std::deque<LevenshteinPotencial<SIZE> > toProcess;
|
|
|
|
|
|
|
+ std::multiset<LevenshteinPotencial<SIZE> > toProcess;
|
|
|
|
|
|
|
|
for (SIZE i =0; i < aSize; i++)
|
|
for (SIZE i =0; i < aSize; i++)
|
|
|
{
|
|
{
|
|
|
items[i] = new int[bSize]();
|
|
items[i] = new int[bSize]();
|
|
|
- toProcess.push_back(LevenshteinPotencial<SIZE>(0, i, i));
|
|
|
|
|
|
|
+ toProcess.insert(LevenshteinPotencial<SIZE>(0, i, i));
|
|
|
|
|
|
|
|
for (SIZE j=0; j < bSize; j++)
|
|
for (SIZE j=0; j < bSize; j++)
|
|
|
items[i][j] = -1;
|
|
items[i][j] = -1;
|
|
|
}
|
|
}
|
|
|
for (SIZE i =1; i < bSize; i++)
|
|
for (SIZE i =1; i < bSize; i++)
|
|
|
- toProcess.push_back(LevenshteinPotencial<SIZE>(i, 0, i));
|
|
|
|
|
|
|
+ toProcess.insert(LevenshteinPotencial<SIZE>(i, 0, i));
|
|
|
while (toProcess.size())
|
|
while (toProcess.size())
|
|
|
{
|
|
{
|
|
|
- auto currentIt = toProcess.cbegin();
|
|
|
|
|
|
|
+ const auto currentIt = toProcess.cbegin();
|
|
|
const LevenshteinPotencial<SIZE> ¤t = *(currentIt);
|
|
const LevenshteinPotencial<SIZE> ¤t = *(currentIt);
|
|
|
|
|
|
|
|
int add = levenshtein_get(items, current.coords.first -1, current.coords.second);
|
|
int add = levenshtein_get(items, current.coords.first -1, current.coords.second);
|
|
@@ -99,28 +99,41 @@ unsigned int levenshtein(const T &a, const T &b, const SIZE aSize, const SIZE bS
|
|
|
}
|
|
}
|
|
|
items[current.coords.first][current.coords.second] = min;
|
|
items[current.coords.first][current.coords.second] = min;
|
|
|
if (current.coords.first == aSize -1 && current.coords.second == bSize -1)
|
|
if (current.coords.first == aSize -1 && current.coords.second == bSize -1)
|
|
|
- return min;
|
|
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
//update toProcess
|
|
//update toProcess
|
|
|
- for (auto i = toProcess.begin(); i != toProcess.end(); i++)
|
|
|
|
|
|
|
+ add = rem = mod = -1;
|
|
|
|
|
+ for (auto i = toProcess.cbegin(); i != toProcess.cend(); i++)
|
|
|
{
|
|
{
|
|
|
if (*i == std::pair<SIZE, SIZE>(current.coords.first, current.coords.second +1))
|
|
if (*i == std::pair<SIZE, SIZE>(current.coords.first, current.coords.second +1))
|
|
|
|
|
+ {
|
|
|
|
|
+ add = (*i).minValue;
|
|
|
toProcess.erase(i);
|
|
toProcess.erase(i);
|
|
|
|
|
+ }
|
|
|
else if (*i == std::pair<SIZE, SIZE>(current.coords.first +1, current.coords.second))
|
|
else if (*i == std::pair<SIZE, SIZE>(current.coords.first +1, current.coords.second))
|
|
|
|
|
+ {
|
|
|
|
|
+ rem = (*i).minValue;
|
|
|
toProcess.erase(i);
|
|
toProcess.erase(i);
|
|
|
|
|
+ }
|
|
|
else if (*i == std::pair<SIZE, SIZE>(current.coords.first +1, current.coords.second +1))
|
|
else if (*i == std::pair<SIZE, SIZE>(current.coords.first +1, current.coords.second +1))
|
|
|
|
|
+ {
|
|
|
|
|
+ mod = (*i).minValue;
|
|
|
toProcess.erase(i);
|
|
toProcess.erase(i);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
if (current.coords.second +1 < bSize && items[current.coords.first][current.coords.second +1] == -1)
|
|
if (current.coords.second +1 < bSize && items[current.coords.first][current.coords.second +1] == -1)
|
|
|
- toProcess.push_back(LevenshteinPotencial<SIZE>(current.coords.first, current.coords.second +1, min +1));
|
|
|
|
|
|
|
+ toProcess.insert(LevenshteinPotencial<SIZE>(current.coords.first, current.coords.second +1, add == -1 ? min +1 : std::min(min +1, add)));
|
|
|
if (current.coords.first +1 < aSize && items[current.coords.first +1][current.coords.second] == -1)
|
|
if (current.coords.first +1 < aSize && items[current.coords.first +1][current.coords.second] == -1)
|
|
|
- toProcess.push_back(LevenshteinPotencial<SIZE>(current.coords.first +1, current.coords.second, min +1));
|
|
|
|
|
|
|
+ toProcess.insert(LevenshteinPotencial<SIZE>(current.coords.first +1, current.coords.second, rem == -1 ? min +1 : std::min(min +1, rem)));
|
|
|
if (current.coords.first +1 < aSize && current.coords.second +1 < bSize &&
|
|
if (current.coords.first +1 < aSize && current.coords.second +1 < bSize &&
|
|
|
items[current.coords.first +1][current.coords.second +1] == -1)
|
|
items[current.coords.first +1][current.coords.second +1] == -1)
|
|
|
- toProcess.push_back(LevenshteinPotencial<SIZE>(current.coords.first +1, current.coords.second +1, min));
|
|
|
|
|
|
|
+ toProcess.insert(LevenshteinPotencial<SIZE>(current.coords.first +1, current.coords.second +1, mod == -1 ? min : std::min(mod, min)));
|
|
|
toProcess.erase(currentIt);
|
|
toProcess.erase(currentIt);
|
|
|
- std::sort(toProcess.begin(), toProcess.end());
|
|
|
|
|
}
|
|
}
|
|
|
- return items[aSize -1][bSize -1];
|
|
|
|
|
|
|
+ const unsigned int levenshtein = items[aSize -1][bSize -1];
|
|
|
|
|
+ for (SIZE i =0; i < aSize; i++)
|
|
|
|
|
+ delete[] items[i];
|
|
|
|
|
+ delete[] items;
|
|
|
|
|
+ return levenshtein;
|
|
|
}
|
|
}
|
|
|
|
|
|