File tree Expand file tree Collapse file tree 3 files changed +49
-0
lines changed
Expand file tree Collapse file tree 3 files changed +49
-0
lines changed Original file line number Diff line number Diff line change @@ -130,6 +130,10 @@ void write_integer(
130130 */
131131[[nodiscard]] auto words_view (string_view text);
132132
133+ /* * Computes the Levenshtein distance between the two strings. */
134+ [[nodiscard, gnu::const ]] auto levenshtein_distance (
135+ string_view first, string_view second) -> size_t;
136+
133137// / @}
134138
135139/*
Original file line number Diff line number Diff line change 2323#include < ranges>
2424#include < string>
2525#include < string_view>
26+ #include < vector>
2627
2728namespace {
2829
@@ -150,4 +151,31 @@ auto split_at_first_space_or_newline(const string_view input) -> StringViewPair
150151 };
151152}
152153
154+ auto levenshtein_distance (
155+ const string_view first, const string_view second) -> size_t
156+ {
157+ const auto size_a = first.size ();
158+ const auto size_b = second.size ();
159+
160+ auto distances = std::views::iota (0uz, size_b + 1uz)
161+ | std::ranges::to<std::vector>();
162+
163+ for (auto i = 0uz; i < size_a; ++i) {
164+ auto prevDist = 0uz;
165+
166+ for (auto j = 0uz; j < size_b; ++j) {
167+ const auto next = distances.at (j + 1uz);
168+
169+ const auto dist = std::exchange (prevDist, next)
170+ + (first.at (i) == second.at (j) ? 0uz : 1uz);
171+
172+ distances.at (j + 1uz) = std::min ({ dist,
173+ distances.at (j) + 1uz,
174+ next + 1uz });
175+ }
176+ }
177+
178+ return distances.at (size_b);
179+ }
180+
153181} // namespace util::strings
Original file line number Diff line number Diff line change @@ -219,3 +219,20 @@ TEST_CASE("Strings - words_view()", TAGS)
219219 REQUIRE (words.back () == " 456" );
220220 }
221221}
222+
223+ TEST_CASE (" Strings - Levenshtein distance" , TAGS)
224+ {
225+ using util::strings::levenshtein_distance;
226+
227+ REQUIRE (
228+ levenshtein_distance (" kitten" , " sitting" ) == 3uz);
229+
230+ REQUIRE (
231+ levenshtein_distance (" corporate" , " cooperation" ) == 5uz);
232+
233+ REQUIRE (
234+ levenshtein_distance (" 123" , { }) == 0uz);
235+
236+ REQUIRE (
237+ levenshtein_distance ({ }, { }) == 0uz);
238+ }
You can’t perform that action at this time.
0 commit comments