#include #include std::vector get_next_vector(const std::string& s) { std::vector next(s.size() + 1); next[0] = -1; for (int i = 0; i < next.size() - 1; i++) { // 实际上写入下一位 int j = next[i]; while (j != -1 && s[i] != s[j]) { // j = -1: 完全不匹配,s[i]==s[j]: 直接能用 j = next[j]; } if (j == -1 || s[i] == s[j]) { j++; } next[i + 1] = j; } return next; } std::vector get_optimized_next_vector(const std::string& s, const std::vector& next) { std::vector next_optimized(next.size()); next_optimized[0] = -1; next_optimized[next.size() - 1] = next[next.size() - 1]; for (int i = 1; i < next.size() - 1; i++) { if (s[next[i]] == s[i]) { next_optimized[i] = next_optimized[next[i]]; } else { next_optimized[i] = next[i]; } } return next_optimized; } std::vector find_substring_pos(const std::string& target, const std::string& pattern) { std::vector matched_pos; const std::vector next_vector = get_optimized_next_vector(pattern, get_next_vector(pattern)); int j = 0; for (int i = 0; i < target.size(); i++) { while (j > -1 && target[i] != pattern[j]) { j = next_vector[j]; } if (j == -1) { j = 0; // 完全失配,直接 i++ j++ continue; } if (target[i] == pattern[j]) { j++; } if (j == pattern.size()) { matched_pos.push_back(i - static_cast(pattern.size()) + 1); j = next_vector[j]; } } return matched_pos; } std::ostream& operator<<(std::ostream& os, std::vector vec) { for (const auto& elem : vec) { os << elem << " "; } return os; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::string target, pattern; std::cin >> target >> pattern; std::clog << get_next_vector(pattern) << std::endl; std::clog << get_optimized_next_vector(pattern, get_next_vector(pattern)) << std::endl; for (const auto i : find_substring_pos(target, pattern)) { std::cout << i << " "; } std::cout << std::endl; return 0; }