#include <cstdio>
#include <string>

using namespace std;

void nextArr(int next[], string s){

int n = s.size();

if(n == 0){
return;
}
// 初始化数组[0,1]位置的值
next[0] = -1;
if(n == 1){
return;
}
next[1] = 0;
// 初始化j和k
// j 为当前位置(实际是求j+1位置的最大前缀和)
// k 为当前位置的最大前缀和长度及失配的位置
int k = next[1];
int j = 1;

// j 到 n - 2时,求的是j = n - 1位置的next值
while (j < n - 1){
// 如果 k 回溯到0位置或者当前字符与当前位置对应的前缀的失配位置比较,
// 则next[++j] = k + 1;
if(k < 0 || s[j] == s[k]){
next[++j] = k + 1;
k = next[j];
}else{
k = next[k];
}
}
}

int kmp(string s1, string s2, int next[]){

int i = 0, j = 0, n = s2.size();
int count = 0;
while (i < s1.size()){
// 如果匹配则指针都向后移动一位
// j = -1,代表next数组回溯到0位置了,
// 此时需要用s1的失配位置和s2的开头逐个匹配了
if(j == -1 || s1[i]==s2[j]){
i++;
j++;
}else{
j = next[j];
}

if(j==n){ // 匹配到一个

// 求匹配个数
{
count++;
i--; //
j = next[j - 1];
}
// return i - j; // 求开始位置
}
}

return count;
}

void print(int a[], int n){
for (int i = 0; i < n; ++i) {
printf("%d ", a[i]);
}
printf("\n");
}

int main(){

string s1 = "badbababbabadbababbababb";
string s2 = "bababb";

int n = s2.size();
int next[n];
nextArr(next, s2);

print(next, n);

int count = kmp(s1, s2, next);

printf("%d", count);
return 0;
}