import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * <p> * 计算模板串S在文本串T中出现了多少次 * * @param T string字符串 模板串 * @param S string字符串 文本串 * @return int整型 */ public int kmp(String T, String S) { char[] sArr = S.toCharArray(); char[] tArr = T.toCharArray(); int s = 0; int t = 0; int count = 0; int[] next = getNext(T); System.out.println(Arrays.toString(next)); while (s < sArr.length) { if (sArr[s] == tArr[t]) { s++; t++; } else if (t == 0) { s++; } else { t = next[t]; } // 设虚拟串为T+' ' ,问题在S中匹配T转换为在S中匹配T+' ' // 当t == tArr.length时认为T+' '没有匹配到,但此时T已经匹配到,count++, // 而T+' '则根据next数组继续回溯匹配 if (t == tArr.length) { count++; t = next[t]; } } return count; } private int[] getNext(String T) { // 设len为T的长度,在原生KMP的next数组上加一个位置next[len],用于记录T[0]~T[len-1]的最长公共前缀长度 T = T + 'z'; char[] tArr = T.toCharArray(); int[] next = new int[tArr.length]; int i = 1; int k = 0; next[0] = -1; while (i < tArr.length - 1) { if (tArr[k] == tArr[i]) { ++i; ++k; if (tArr[i] != tArr[k]) { next[i] = k; } else { next[i] = next[k]; } } else if (k == 0) { next[++i] = 0; } else { k = next[k]; } } return next; } }