Files
exercises/dsa/ch4_string/template_kmp_elegent.cpp
T

47 lines
1.2 KiB
C++

#include <iostream>
#include <vector>
std::vector<int> prefix_function(const std::string& s) {
std::vector<int> pi(s.size());
for (int i = 1; i < s.size(); i++) {
int j = pi[i - 1];
while (j > 0 && s[i] != s[j]) {
j = pi[j - 1];
}
if (s[i] == s[j]) { j++; }
pi[i] = j;
}
return pi;
}
std::vector<int> find_substring_pos(const std::string& target, const std::string& pattern) {
std::vector<int> matched_pos;
const std::vector<int> pattern_prefix_values = prefix_function(pattern);
int j = 0;
for (int i = 0; i < target.size(); i++) {
while (j > 0 && target[i] != pattern[j]) {
j = pattern_prefix_values[j - 1];
}
if (target[i] == pattern[j]) { j++; }
if (j == pattern.size()) {
matched_pos.push_back(i - static_cast<int>(pattern.size()) + 1);
j = pattern_prefix_values[j - 1];
}
}
return matched_pos;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::string target, pattern;
std::cin >> target >> pattern;
for (const auto i : find_substring_pos(target, pattern)) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}