diff --git a/string/kmp.cpp b/string/kmp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f542fd41ea4807aab496af0b8147e8e67beaf132 --- /dev/null +++ b/string/kmp.cpp @@ -0,0 +1,44 @@ +/** + * Knuth-Morris-Pratt - KMP + * + * Complexity (Time): + * preprocess -> O(m) + * search -> O(n) + * Complexity (Space): O(n + m) + */ + +int table[MAX]; +vector<int> occurs; + +// Build the table where table[i] is the longest prefix of patt[0..i] which is +// also a sufix of patt[0..i] +void preprocess(string patt) { + int i = 1, len = 0; + + while (i < patt.size()) { + if (patt[i] == patt[len]) + table[i++] = ++len; + else if (len) + len = table[len - 1]; + else + table[i++] = 0; + } +} + +// Search for occurrences of patt in txt and add indexes of matches to occurs +void search(string patt, string txt) { + int i = 0, j = 0; + + while (i < txt.size()) { + if (patt[j] == txt[i]) + i++, j++; + + if (j == patt.size()) { + occurs.push_back(i - j); // Pattern found at (i - j) + j = table[j - 1]; + } else if (i < txt.size() && patt[j] != txt[i]) { + if (j) j = table[j - 1]; + else i++; + } + } +}