C++ Utilities 5.37.0
Useful C++ classes and routines such as argument parser, IO and conversion utilities
Loading...
Searching...
No Matches
levenshtein.cpp
Go to the documentation of this file.
1#include "./levenshtein.h"
2
3#include "./math.h"
4#include "./multiarray.h"
5
6#include <limits>
7
8using namespace std;
9
10namespace CppUtilities {
11
13
16
29void initDistanceArray(DistanceArray &distanceArray, const size_t size1, const size_t size2)
30{
31 const auto maxDistance(size1 + size2);
32 // ignore warning about null pointer dereference for now (which is *likely* not correct)
34 CPP_UTILITIES_WARNING_DISABLE("-Wnull-dereference")
35 distanceArray.at(0, 0) = maxDistance;
37 for (size_t i = 0; i <= size1; ++i) {
38 distanceArray.at(i + 1, 1) = i;
39 distanceArray.at(i + 1, 0) = maxDistance;
40 }
41 for (size_t i = 0; i <= size2; ++i) {
42 distanceArray.at(1, i + 1) = i;
43 distanceArray.at(0, i + 1) = maxDistance;
44 }
45}
46
49size_t performDamerauLevenshteinAlgorithm(
50 DistanceArray &distanceArray, const char *const str1, const size_t size1, const char *const str2, const size_t size2)
51{
52 size_t dist1[std::numeric_limits<unsigned char>::max() + 1] = { 0 };
53 for (size_t index1 = 1; index1 <= size1; ++index1) {
54 size_t dist2 = 0;
55 for (size_t index2 = 1; index2 <= size2; ++index2) {
56 const size_t substitution((str1[index1 - 1] == str2[index2 - 1]) ? 0 : 1);
57 const size_t transposition1(dist1[static_cast<unsigned char>(str2[index2 - 1])]);
58 const size_t transposition2(dist2);
59 if (!substitution) {
60 dist2 = index2;
61 }
62 // clang-format off
63 distanceArray.at(index1 + 1, index2 + 1) = CppUtilities::min(
64 distanceArray.at(index1, index2) + substitution, // substitution
65 distanceArray.at(index1 + 1, index2) + 1, // insertion
66 distanceArray.at(index1, index2 + 1) + 1, // deletion
67 distanceArray.at(transposition1, transposition2) + (index1 - transposition1 - 1) + 1 + (index2 - transposition2 - 1) // transposition
68 );
69 // clang-format on
70 }
71 dist1[static_cast<int>(str1[index1 - 1])] = index1;
72 }
73 return distanceArray.at(size1 + 1, size2 + 1);
74}
75
77template <typename DistanceArray>
78size_t performDamerauLevenshteinAlgorithmAllocatingOnHeap(
79 DistanceArray &distanceArray, const char *const str1, const size_t size1, const char *const str2, const size_t size2)
80{
81 std::vector<size_t> buffer(distanceArray.totalSize());
82 distanceArray.buffer() = buffer.data();
83 initDistanceArray(distanceArray, size1, size2);
84 return performDamerauLevenshteinAlgorithm(distanceArray, str1, size1, str2, size2);
85}
86
89template <typename DistanceArray>
90size_t performDamerauLevenshteinAlgorithmAllocatingOnStack(
91 DistanceArray &distanceArray, const char *const str1, const size_t size1, const char *const str2, const size_t size2)
92{
93 size_t buffer[128] = { 0 };
94 distanceArray.buffer() = buffer;
95 initDistanceArray(distanceArray, size1, size2);
96 return performDamerauLevenshteinAlgorithm(distanceArray, str1, size1, str2, size2);
97}
98
100
119std::size_t computeDamerauLevenshteinDistance(const char *const str1, const size_t size1, const char *const str2, const size_t size2)
120{
121 // allocate distance array
122 auto distanceArray(makeNoneOwningMultiArray<std::size_t>(size1 + 2, size2 + 2));
123 if (distanceArray.totalSize() <= 128) {
124 return performDamerauLevenshteinAlgorithmAllocatingOnStack(distanceArray, str1, size1, str2, size2);
125 } else {
126 return performDamerauLevenshteinAlgorithmAllocatingOnHeap(distanceArray, str1, size1, str2, size2);
127 }
128}
129
130} // namespace CppUtilities
#define CPP_UTILITIES_WARNING_PUSH
Causes GCC/Clang to remember the state of the diagnostics.
Definition global.h:154
#define CPP_UTILITIES_WARNING_POP
Causes GCC/Clang to restore the previous state of the diagnostics.
Definition global.h:155
#define CPP_UTILITIES_WARNING_DISABLE(text)
Causes GCC/Clang to suppress the specified diagnostic.
Definition global.h:156
The MultiArray class provides an N-dimensional array.
Definition multiarray.h:76
Contains all utilities provided by the c++utilities library.
auto makeNoneOwningMultiArray(DimensionSizes... dimensionSizes)
Constructs a new N-dimensional array using a caller-managed buffer as underlying container....
Definition multiarray.h:185
constexpr T min(T first, T second)
Returns the smallest of the given items.
Definition math.h:84
CPP_UTILITIES_EXPORT std::size_t computeDamerauLevenshteinDistance(const char *str1, std::size_t size1, const char *str2, std::size_t size2)
STL namespace.
constexpr int i