KMP【模板】
来源:互联网 发布:驱鼠器真的有用吗 知乎 编辑:程序博客网 时间:2024/05/02 00:49
当字符串匹配失败时,模式串的指针并没有指向0从头比较,而是指向了一个特定的位置,因为这个Next[j]指向的位置pos前长度为Next[pos]的子串,同模式串第j位前的长度为Next[j]的子串是相同的。
即S[0]~S[Next[j]]一定与S[len-1-Next[j]]~S[j-1]匹配。
1.既能做前缀又能做后缀的子串长度
ans[0] = len; int id = 1,i = len; while(Next[i] > 0) { ans[id++] = Next[i]; i = Next[i]; }
2.求最短子串长度
给定的字符串s,最短的重复子串a是s[Next[len]] s[Next[len+1]] … s[len-1]。
当len % Next[len] = 0时,说明字符串s有不是它本身重复子串a,最大的n为len/Next[len]。当len % Next[len] != 0时,除了s,没有重复子串a满足要求,这时n = 1。
if(len % (len-Next[len]) == 0) cout << len/(len-Next[len]) << endl; else cout << 1 << endl;
3.求模式串pat在主串str中匹配次数
可重叠匹配:当一次匹配成功后,j继续回退到Next[j]向后进行匹配,直到主串str的末尾。
不可重叠匹配:当一次匹配成功后,j继续回退到0向后进行匹配,直到主串str的末尾。
4.求N行M列的字符矩阵,最小的字符子矩阵的面积
每一行s[i]来说,M-Next[M]是最小的,对于每一列s[j]来说,N-Next[N]是最小的。
分别求每一行的最小公倍数lcmn和每一列的最小公倍数lcmm。最后结果就是lcmn*lcmm。
5.求字符串s的循环前缀的长度和循环的次数
对于当前前缀S[1]~S[i],如果i % (i-Next[i]) == 0,则i - Next[i]就是最小重复子串,即循环节长度为i - Next[i]。循环次数为i / (i - Next[i])。
char str[1000010],pat[1000010];//pat为模式串,str为主串int Next[1000010]; //Next[x]下标x表示匹配失败处字符下标//模式串pat的前缀与x位置的后缀的最大匹配字符个数-1void GetNext(char *pat){ int LenPat = strlen(pat); int i = 0,j = -1; Next[0] = -1; while(i < LenPat) { if(j == -1 || pat[i] == pat[j]) { i++,j++; Next[i] = j; } else j = Next[j]; }}int KMP()//返回模式串pat在str中第一次出现的位置{ int LenStr = strlen(str); int LenPat = strlen(pat); GetNext(pat); int i = 0,j = 0; int ans = 0;//计算模式串在主串匹配次数 while(i < LenStr) { if(j == -1 || str[i] == pat[j]) i++,j++; else j = Next[j]; if(j == LenPat) { //ans++; ans存放匹配次数,去掉return,最后返回ans return i - LenPat + 1; } } return -1;//没找到匹配位置 //return ans;//返回匹配次数。}
- KMP模板
- KMP 模板
- kmp模板
- kmp模板
- kmp模板
- KMP模板
- kmp模板
- kmp模板
- KMP 模板
- 【模板】KMP
- KMP模板
- KMP模板
- 【KMP 模板】
- KMP模板
- KMP 模板
- kmp模板
- KMP模板
- KMP 模板
- RPM 使用
- 使用Java添加系统右键菜单--详解版
- poj2251 Dungeon Master
- Android蓝牙应用程序开发的基本步骤
- 扑克牌顺子
- KMP【模板】
- Java开发中的23种设计模式详解(转)
- 用Gson和SharedPreferences轻松构建android本地数据缓存
- 第三次C#作业-Excel数据读取及HTML文件初步
- TASK 重新加载宿主
- Unity3D研究之2D游戏开发制作原理
- <<诫子书>> 诸葛亮
- spring @Autowired和@@Qualifier 混合使用的例子
- 三种重要哈希介绍