RapidFuzz
Loading...
Searching...
No Matches
Hamming_impl.hpp
1/* SPDX-License-Identifier: MIT */
2/* Copyright © 2021 Max Bachmann */
3
4#pragma once
5#include <rapidfuzz/details/Range.hpp>
6#include <rapidfuzz/details/distance.hpp>
7#include <stdexcept>
8
9namespace rapidfuzz {
10namespace detail {
11
12class Hamming : public DistanceBase<Hamming, size_t, 0, std::numeric_limits<int64_t>::max(), bool> {
13 friend DistanceBase<Hamming, size_t, 0, std::numeric_limits<int64_t>::max(), bool>;
14 friend NormalizedMetricBase<Hamming, bool>;
15
16 template <typename InputIt1, typename InputIt2>
17 static size_t maximum(const Range<InputIt1>& s1, const Range<InputIt2>& s2, bool)
18 {
19 return std::max(s1.size(), s2.size());
20 }
21
22 template <typename InputIt1, typename InputIt2>
23 static size_t _distance(const Range<InputIt1>& s1, const Range<InputIt2>& s2, bool pad,
24 size_t score_cutoff, size_t)
25 {
26 if (!pad && s1.size() != s2.size()) throw std::invalid_argument("Sequences are not the same length.");
27
28 size_t min_len = std::min(s1.size(), s2.size());
29 size_t dist = std::max(s1.size(), s2.size());
30 auto iter_s1 = s1.begin();
31 auto iter_s2 = s2.begin();
32 for (size_t i = 0; i < min_len; ++i)
33 dist -= bool(*(iter_s1++) == *(iter_s2++));
34
35 return (dist <= score_cutoff) ? dist : score_cutoff + 1;
36 }
37};
38
39template <typename InputIt1, typename InputIt2>
40Editops hamming_editops(const Range<InputIt1>& s1, const Range<InputIt2>& s2, bool pad, size_t)
41{
42 if (!pad && s1.size() != s2.size()) throw std::invalid_argument("Sequences are not the same length.");
43
44 Editops ops;
45 size_t min_len = std::min(s1.size(), s2.size());
46 size_t i = 0;
47 for (; i < min_len; ++i)
48 if (s1[i] != s2[i]) ops.emplace_back(EditType::Replace, i, i);
49
50 for (; i < s1.size(); ++i)
51 ops.emplace_back(EditType::Delete, i, s2.size());
52
53 for (; i < s2.size(); ++i)
54 ops.emplace_back(EditType::Insert, s1.size(), i);
55
56 ops.set_src_len(s1.size());
57 ops.set_dest_len(s2.size());
58 return ops;
59}
60
61} // namespace detail
62} // namespace rapidfuzz