import java.util.*;
/*
sb题真难
kmp算法的核心思想在于指向T串的指针i永远不回退,当出现不匹配时,指向S串的指针j进行连续回退;
所以需要对S串求next数组,怎么求的没看明白.
*/

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算模板串S在文本串T中出现了多少次
     * @param S string字符串 模板串
     * @param T string字符串 文本串
     * @return int整型
     */
    public int[] getNext(String S)
    {
        int m = S.length();
        int[] next = new int[m];
        for(int j=0,i=1;i<m;i++)
        {
            //j>0,避免数组越界
            while(j>0 && S.charAt(i)!=S.charAt(j))
            {
                j=next[j-1];
            }

            if(S.charAt(j)==S.charAt(i)) j++;
            next[i]=j;
        }
        return next;
    }

    public int kmp (String S, String T) {
        // write code here
        int m = S.length();
        int n = T.length();
        if(m>n || n==0) return 0;
        int cnt=0;

        int[] next = getNext(S);
        //i指向T,永远不回退
        //j指向S,不匹配时回退
        for(int i=0,j=0;i<n;i++)
        {
            //j的回退是连续的,j>0避免数组越界
            while(j>0 && S.charAt(j)!=T.charAt(i))
            {
                j=next[j-1];
            }

            if(S.charAt(j)==T.charAt(i)) j++;
            if(j==m)
            {
                cnt++;
                j=next[j-1];
            }
        }
        
        return cnt;
    }
}