KMP算法应用于 在一篇有n个字母的文档中 查找某个想要查找的长度为m的单词;
暴力枚举:从文档的前m个字母和单词对比,然后是第2到m+1个,然后是第3到m+2个;这样算法复杂度最坏就达到了O(m*n),对于大数据肯定不行。
KMP算法的精髓即设法减少不必要的枚举次数,举个例子;比如已经匹配好了单词的前k-1个字母;但第k个字母无法匹配了;那么如果前k-1个字母中存在类似回文的情况(前i个字母组成的子串和后i个字母组成的子串相同),那么指针j就变成i(相当于整体往右移动),这样来达到减少枚举次数的目的;因此 可以预先处理 要找的单词,next【i】=t保存单词的前面i-1个字母中,前t个字母组成的子串和后t个字母组成的子串相同; 并且t尽可能大;
如何来求next【i】呢?初始化next【0】=next【1】=0;从前往后递推;令j=next【i-1】;则表示前i-2个字母中前j个字母和后j个字母相同;那么如果s【j】(第j+1个字母)==s【i-1】(第i个字母),next【i】就等于next【j】+1;如果不相等,那么j变成next【j】;
看了2节晚自习才看明白。。确实不大好理解。。。
下面这题是一个很小的应用:(poj2752,yzoi1780)
题目大意:给定一个长度小于400000的字符串s,要求求出所有i;i满足s的前i个字母组成的子串和后i个字母组成的字串相同;
要求将所有i递增输出;
这题只要求出next数组就好;注意要多求一位(算到next【len】位置);j=len;next【j】=t就是s的前t个字母和后t个字母相同;这样就求出了第二大的i(最大的i就是字符串的长度);然后每次循环j=next【j】;next【j】的值就是一个i的值(注意去掉0);