Skip to content

Commit 6ab9e08

Browse files
Merge branch 'master' into iterative_quick_sort
2 parents f8ac592 + fe41cf4 commit 6ab9e08

File tree

2 files changed

+62
-58
lines changed

2 files changed

+62
-58
lines changed

DIRECTORY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
* [Searching Of Element In Dynamic Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/searching_of_element_in_dynamic_array.cpp)
120120
* [Shortest Common Supersequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/shortest_common_supersequence.cpp)
121121
* [Subset Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/subset_sum.cpp)
122+
* [Trapped Rainwater](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/trapped_rainwater.cpp)
122123
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/tree_height.cpp)
123124
* [Word Break](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/word_break.cpp)
124125

@@ -161,7 +162,7 @@
161162
* [Boruvkas Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/boruvkas_minimum_spanning_tree.cpp)
162163
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/dijkstra.cpp)
163164
* [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/huffman.cpp)
164-
* [Jumpgame](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jumpgame.cpp)
165+
* [Jump Game](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jump_game.cpp)
165166
* [Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/knapsack.cpp)
166167
* [Kruskals Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/kruskals_minimum_spanning_tree.cpp)
167168
* [Prims Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/prims_minimum_spanning_tree.cpp)

strings/knuth_morris_pratt.cpp

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,98 @@
11
/**
2-
* \file
3-
* \brief The [Knuth-Morris-Pratt
2+
* @file
3+
* @brief The [Knuth-Morris-Pratt
44
* Algorithm](https://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm) for
55
* finding a pattern within a piece of text with complexity O(n + m)
6-
*
6+
* @details
77
* 1. Preprocess pattern to identify any suffixes that are identical to
88
* prefixes. This tells us where to continue from if we get a mismatch between a
99
* character in our pattern and the text.
1010
* 2. Step through the text one character at a time and compare it to a
1111
* character in the pattern updating our location within the pattern if
1212
* necessary
13+
* @author [Yancey](https://github.com/Yancey2023)
1314
*/
1415

15-
#include <iostream>
16-
#ifdef _MSC_VER
17-
#include <string> // use this for MS Visual C++
18-
#else
19-
#include <cstring>
20-
#endif
21-
#include <vector>
16+
#include <cassert> /// for assert
17+
#include <iostream> /// for IO operations
18+
#include <string> /// for std::string
19+
#include <vector> /// for std::vector
2220

23-
/** \namespace string_search
24-
* \brief String search algorithms
21+
/**
22+
* @namespace string_search
23+
* @brief String search algorithms
2524
*/
2625
namespace string_search {
2726
/**
28-
* Generate the partial match table aka failure function for a pattern to
27+
* @brief Generate the partial match table aka failure function for a pattern to
2928
* search.
30-
* \param[in] pattern text for which to create the partial match table
31-
* \returns the partial match table as a vector array
29+
* @param pattern text for which to create the partial match table
30+
* @returns the partial match table as a vector array
3231
*/
33-
std::vector<int> getFailureArray(const std::string &pattern) {
34-
int pattern_length = pattern.size();
35-
std::vector<int> failure(pattern_length + 1);
36-
failure[0] = -1;
37-
int j = -1;
38-
32+
std::vector<size_t> getFailureArray(const std::string &pattern) {
33+
size_t pattern_length = pattern.size();
34+
std::vector<size_t> failure(pattern_length + 1);
35+
failure[0] = std::string::npos;
36+
size_t j = std::string::npos;
3937
for (int i = 0; i < pattern_length; i++) {
40-
while (j != -1 && pattern[j] != pattern[i]) {
38+
while (j != std::string::npos && pattern[j] != pattern[i]) {
4139
j = failure[j];
4240
}
43-
j++;
44-
failure[i + 1] = j;
41+
failure[i + 1] = ++j;
4542
}
4643
return failure;
4744
}
4845

4946
/**
50-
* KMP algorithm to find a pattern in a text
51-
* \param[in] pattern string pattern to search
52-
* \param[in] text text in which to search
53-
* \returns `true` if pattern was found
54-
* \returns `false` if pattern was not found
47+
* @brief KMP algorithm to find a pattern in a text
48+
* @param pattern string pattern to search
49+
* @param text text in which to search
50+
* @returns the starting index of the pattern if found
51+
* @returns `std::string::npos` if not found
5552
*/
56-
bool kmp(const std::string &pattern, const std::string &text) {
57-
int text_length = text.size(), pattern_length = pattern.size();
58-
std::vector<int> failure = getFailureArray(pattern);
59-
60-
int k = 0;
61-
for (int j = 0; j < text_length; j++) {
62-
while (k != -1 && pattern[k] != text[j]) {
53+
size_t kmp(const std::string &pattern, const std::string &text) {
54+
if (pattern.empty()) {
55+
return 0;
56+
}
57+
std::vector<size_t> failure = getFailureArray(pattern);
58+
size_t text_length = text.size();
59+
size_t pattern_length = pattern.size();
60+
size_t k = 0;
61+
for (size_t j = 0; j < text_length; j++) {
62+
while (k != std::string::npos && pattern[k] != text[j]) {
6363
k = failure[k];
6464
}
65-
k++;
66-
if (k == pattern_length)
67-
return true;
65+
if (++k == pattern_length) {
66+
return j - k + 1;
67+
}
6868
}
69-
return false;
69+
return std::string::npos;
7070
}
7171
} // namespace string_search
7272

7373
using string_search::kmp;
7474

75-
/** Main function */
76-
int main() {
77-
std::string text = "alskfjaldsabc1abc1abc12k23adsfabcabc";
78-
std::string pattern = "abc1abc12l";
79-
80-
if (kmp(pattern, text) == true) {
81-
std::cout << "Found" << std::endl;
82-
} else {
83-
std::cout << "Not Found" << std::endl;
84-
}
75+
/**
76+
* @brief self-test implementations
77+
* @returns void
78+
*/
79+
static void tests() {
80+
assert(kmp("abc1abc12l", "alskfjaldsabc1abc1abc12k2") == std::string::npos);
81+
assert(kmp("bca", "abcabc") == 1);
82+
assert(kmp("World", "helloWorld") == 5);
83+
assert(kmp("c++", "his_is_c++") == 7);
84+
assert(kmp("happy", "happy_coding") == 0);
85+
assert(kmp("", "pattern is empty") == 0);
8586

86-
text = "abcabc";
87-
pattern = "bca";
88-
if (kmp(pattern, text) == true) {
89-
std::cout << "Found" << std::endl;
90-
} else {
91-
std::cout << "Not Found" << std::endl;
92-
}
87+
// this lets the user know that the tests have passed
88+
std::cout << "All KMP algorithm tests have successfully passed!\n";
89+
}
9390

91+
/*
92+
* @brief Main function
93+
* @returns 0 on exit
94+
*/
95+
int main() {
96+
tests();
9497
return 0;
9598
}

0 commit comments

Comments
 (0)