From 1ede4333f68e2541d0073fb7a9f59280dbe68e2d Mon Sep 17 00:00:00 2001 From: kindofman <43539680+kindofman@users.noreply.github.com> Date: Sun, 29 Dec 2019 09:33:17 +0300 Subject: [PATCH] Update main.cpp --- 16-1/main.cpp | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/16-1/main.cpp b/16-1/main.cpp index 6bf3cd9..b664a33 100644 --- a/16-1/main.cpp +++ b/16-1/main.cpp @@ -3,3 +3,76 @@ Найдите все вхождения шаблона в строку. Длина шаблона – p, длина строки ­– n. Время O(n + p), доп. память – O(p). Вариант 1. С помощью префикс-функции (алгоритм Кнута-Морриса-Пратта). */ + +#include +#include +#include + +using std::cin; +using std::cout; +using std::endl; +using std::vector; +using std::string; + +void print_indices( const vector& indices ) { + for ( auto i: indices ) { + cout << i << ' '; + } + cout << endl; +} + +vector prefix_function ( const string& s ) { + int n = (int) s.length(); + vector pi (n); + pi[0] = 0; + for ( int i = 1; i < n; ++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; +} + +vector prefix_function_mod( const string& templ, const string& s, vector pi_templ ) { + int n = (int) s.length(); + vector pi (n+1); + int prev = 0; + for ( int i = 0; i < n; ++i ) { + int j = prev; + while ( j > 0 && s[i] != templ[j] ) { + j = pi_templ[j-1]; + } + if ( s[i] == templ[j] ) { ++j; } + pi[i] = j; + prev = j; + } + return pi; +} + + +vector count_substring( const string& templ, const string& str ) { + vector result; + vector prefixes_templ = prefix_function( templ ); + vector prefixes = prefix_function_mod( templ, str, prefixes_templ ); + int size_templ = (int) templ.size(); + for ( int i = 0; i < prefixes.size(); ++i ) { + if ( prefixes[i] == size_templ ) { result.push_back( i - size_templ + 1 ); } + } + return result; +} + + +int main() { + string templ; + string str; + std::getline( cin, templ ); + std::getline( cin, str ); + vector indices = count_substring( templ, str ); + print_indices( indices ); + return 0; +} + +