Skip to content

Commit

Permalink
[C++] Knuth–Morris–Pratt (KMP) Algorithm (String Matching) 🔡
Browse files Browse the repository at this point in the history
  • Loading branch information
amanmehara committed Mar 17, 2024
1 parent d78deba commit 87a34fe
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions C++/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@
* Selection Sort

## String Algorithms
* Knuth–Morris–Pratt _(KMP)_ Algorithm
* Rabin-Karp Algorithm
2 changes: 2 additions & 0 deletions C++/string_algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
target_sources(programming
PRIVATE
kmp_matcher.h
kmp_matcher.cpp
rabin_karp_matcher.h
rabin_karp_matcher.cpp)
63 changes: 63 additions & 0 deletions C++/string_algorithms/kmp_matcher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2024 Aman Mehara
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "kmp_matcher.h"

#include <cmath>
#include <string>
#include <vector>

namespace mehara::string {

std::vector<int> compute_prefix_function(const std::string& pattern)
{
int m = pattern.size();
std::vector<int> pi(m);
int k = 0;
for (int q = 1; q < m; q++) {
while (k > 0 && pattern[k] != pattern[q]) {
k = pi[k - 1];
}
if (pattern[k] == pattern[q]) {
k++;
}
pi[q] = k;
}
return pi;
}

std::vector<int> kmp_matcher(const std::string& text,
const std::string& pattern)
{
std::vector<int> matches;
int n = text.size();
int m = pattern.size();
auto pi = compute_prefix_function(pattern);
int q = 0;
for (int i = 0; i < n; i++) {
while (q > 0 && pattern[q] != text[i]) {
q = pi[q - 1];
}
if (pattern[q] == text[i]) {
q++;
}
if (q == m) {
matches.push_back(i - m + 1);
q = pi[q - 1];
}
}
return matches;
}

} // namespace mehara::string
28 changes: 28 additions & 0 deletions C++/string_algorithms/kmp_matcher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2024 Aman Mehara
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef MEHARA_KMP_MATCHER_H_
#define MEHARA_KMP_MATCHER_H_

#include <string>
#include <vector>

namespace mehara::string {

std::vector<int> kmp_matcher(const std::string& text,
const std::string& pattern);

} // namespace mehara::string

#endif // MEHARA_KMP_MATCHER_H_

0 comments on commit 87a34fe

Please sign in to comment.