Pagini recente » Cod sursa (job #880949) | Cod sursa (job #192849) | Cod sursa (job #993605) | Cod sursa (job #2785289) | Cod sursa (job #1748089)
#include <bits/stdc++.h>
using namespace std;
using sit = string::iterator;
pair<int, int> find_self_maximal_prefix_and_period(sit str, const int n){
int period = 1;
for(int i = 1; i < n; ++i){
if(str[i] < str[i-period]){
period = i+1; }
else if(str[i] > str[i-period]){
return make_pair(i, period); } }
return make_pair(n, period); }
int find_self_maximal_period(sit str, const int n){
int j = 0;
while(j < n){
auto p = find_self_maximal_prefix_and_period(str+j, n-j);
if(j+p.first >= n-1) return j;
else j += p.first - (p.first % p.second); } }
template <typename Callback>
void find_all_self_maximal(sit str, const int n, sit pat, const int m, Callback& cb){
int i = 0, j = 0, period = 1;
while(i <= n-m){
while(j < m && pat[j] == str[i+j]){
++j;
if(j > period && pat[j-1] != pat[j-period-1]){
period = j; } }
if(j == m){
cb(i); }
i += period;
if(j >= 2 * period) j -= period;
else j = 0, period = 1; } }
int main(){
ifstream f("strmatch.in");
ofstream g("strmatch.out");
string str, pat;
f >> pat >> str;
int nr_match = 0, prev = -1;
const int su = find_self_maximal_period(begin(pat), pat.size()), sv = pat.size() - su;
auto cb1 = [&](const int i){
if(i - prev > su && equal(begin(pat), begin(pat) + su, begin(str) + i - su)){
prev = i;
++nr_match; } };
find_all_self_maximal(begin(str), str.size(), begin(pat) + su, sv, cb1);
g << nr_match << endl;
nr_match = 0;
prev = -1;
auto cb2 = [&](const int i){
if(i - prev > su && equal(begin(pat), begin(pat) + su, begin(str) + i - su)){
prev = i;
if(nr_match++ < 1000){
g << i-su << ' '; } } };
find_all_self_maximal(begin(str), str.size(), begin(pat) + su, sv, cb2);
return 0; }