Algoteka
Log in to submit your own samples!

Knuth-Morris-Pratt algorithm

Problem by oml1111
# Tech tags Title Creator Created date
1 0
2022-11-19 10:48
View all samples for this language (1 verified and 0 unverified)

O(n + m) Commented solution | C++ |

By oml1111 |
0 likes

An \(O(n+m)\) commented implementation of the Knuth-Morris-Pratt algorithm (\(n\) is the size of the string to be we do the search on, \(m\) is the size of the string for which we count occurrences)

Code

#include<vector>
#include<string>
 
int knuth_morris_pratt_count(std::string s, std::string t) {  // Counts all occurrences of string t in string s
    std::vector<int> kmp(t.size()+1, 0);  // In `t`, maximum prefix [0, kmp[pos]) that corresponds to suffix of [0, pos)
    for(int i=1; i<(int)t.size(); i++) {
        kmp[i+1] = kmp[i];
        while(kmp[i+1] > 0 && t[i] != t[kmp[i+1]]) {  // While end doesn't match t[i]
            kmp[i+1] = kmp[kmp[i+1]];  // Go back along prefixes
        }
        if(t[i] == t[kmp[i+1]]) kmp[i+1]++;  // If match, then extend prefix
    }
    
    int match_len = 0;  // Maximum prefix of `t` we have matched in current position of `s`
    int result = 0;  // Count of occurrences
    for(char c : s) {
        if(match_len == (int)t.size()) {
            match_len = kmp[match_len];  // If match, then go back a prefix
        }
        while(match_len > 0 && c != t[match_len]) {  // While prefix can't be extended
            match_len = kmp[match_len];  // Go back a prefix
        }
        if(c == t[match_len]) {  // Extend prefix length if we can
            match_len++;
        }
        if(match_len == (int)t.size()) result++;  // Match found
    }
    return result;
}

int main() {
    std::string s = "abacababa";
    std::string t = "aba";
    int result = knuth_morris_pratt_count(s, t);
    return 0;
}

References

functions
std::string::operator[] en.cppreference.com cplusplus.com
std::string::size en.cppreference.com cplusplus.com
std::vector::operator[] en.cppreference.com cplusplus.com
classes
std::string en.cppreference.com cplusplus.com
std::vector en.cppreference.com cplusplus.com

Problem Description

Implement the Knuth-Morris-Pratt algorithm and use it to count all occurrences of some string in some other string.

Knuth-Morris-Pratt algorithm - wikipedia.org

View sample discussion (0 comments)
View problem discussion (0 comments)