KMP字符串

例题:

给定一个模式串 S,以及一个模板串 P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

模板串 P 在模式串 S 中多次作为子串出现。

求出模板串 P 在模式串 S 中所有出现的位置的起始下标。

输入格式

第一行输入整数 N,表示字符串 P 的长度。

第二行输入字符串 P

第三行输入整数 M,表示字符串 S 的长度。

第四行输入字符串 S

输出格式

共一行,输出所有出现位置的起始下标(下标从 0 开始计数),整数之间用空格隔开。

数据范围

1N100000
1M1000000

代码:

 #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; }
复制代码

 

posted @   zzq12138  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示