KMP字符串
例题:
给定一个模式串 S,以及一个模板串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。
模板串 P 在模式串 S 中多次作为子串出现。
求出模板串 P 在模式串 S 中所有出现的位置的起始下标。
输入格式
第一行输入整数 N,表示字符串 P 的长度。
第二行输入字符串 P。
第三行输入整数 M,表示字符串 S 的长度。
第四行输入字符串 S。
输出格式
共一行,输出所有出现位置的起始下标(下标从 0 开始计数),整数之间用空格隔开。
数据范围
1≤N≤100000
1≤M≤1000000
代码:
#include<iostream>
using namespace std; const int N=100010,M=1000010; int ne[N],n,m;//ne[1]==0
//对next[ j ] ,是p[ 1, j ]串中前缀和后缀相同的最大长度(部分匹配值),即 p[ 1, next[ j ] ] = p[ j - next[ j ] + 1, j ]。 char s[M],p[N]; int main(){ cin>>n>>p+1>>m>>s+1;//从下标为1的地方读入字符串 for(int i=2,j=0;i<=n;i++){//字符串的长度至少为2时,才会有前后缀,用模式串的后缀(i)与模式串的前缀(j)进行比较
//j的下标之所以从0开始是因为如果是i和j+1比较,可以保证1-j都是可以成功匹配的。
//如果下一步匹配失败(即i和j+1比较),可以直接跳到ne[j] 。如果是i和j比较,那么出现匹配失败,j要减1然后再ne[j] ,还可能出现很多细节问题。
while(j&&p[i]!=p[j+1]) j=ne[j];//如果字符串没有挪到开头并且不匹配时,直接把p串往前移动至下一次可以和前面部分匹配的位置 if(p[i]==p[j+1]) j++; ne[i]=j; } for(int i=1,j=0;i<=m;i++){//匹配过程 while(j&&s[i]!=p[j+1]) j=ne[j]; if(s[i]==p[j+1]) j++; if(j==n)//如果字符串匹配成功 cout<<i-n<<" "; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】