41 lines
1.1 KiB
C++
41 lines
1.1 KiB
C++
#include "iosifovitch.h"
|
|
#include <numeric>
|
|
|
|
auto levenshtein_distance(std::string_view const& a, std::string_view const& b) -> unsigned int {
|
|
if (a.size() == 0 || b.size() == 0) return a.size() + b.size();
|
|
|
|
if (a.size() > b.size()) return levenshtein_distance(b, a);
|
|
|
|
auto i = 0u;
|
|
while (i < a.size() && a[i] == b[i]) ++i;
|
|
|
|
if (i != 0) return levenshtein_distance(a.substr(i), b.substr(i));
|
|
|
|
i = 0;
|
|
while (i && a[a.size() - i] == b[b.size() - i]) ++i;
|
|
if (i != 0) return levenshtein_distance(a.substr(0, a.size() - i), b.substr(0, b.size() - i));
|
|
|
|
auto const buffer_length = a.size() + 1;
|
|
auto buffers = new unsigned int[buffer_length * 2];
|
|
|
|
unsigned int * buffer[2] = {buffers, buffers + buffer_length};
|
|
std::iota(buffer[0], buffer[1], 0);
|
|
std::fill(buffer[1], buffer[1] + buffer_length, 0);
|
|
|
|
for (auto i = 0u; i < b.size(); ++i)
|
|
{
|
|
buffer[1][0] = i + 1;
|
|
for (auto j = 0u; j < a.size(); ++j)
|
|
{
|
|
buffer[1][j + 1] = std::min(
|
|
buffer[0][j] + (a[j] == b[i] ? 0u : 1u),
|
|
std::min(buffer[0][j + 1], buffer[1][j]) + 1u
|
|
);
|
|
}
|
|
std::swap(buffer[0], buffer[1]);
|
|
}
|
|
|
|
auto cost = buffer[0][buffer_length - 1];
|
|
delete [] buffers;
|
|
return cost;
|
|
} |