字符串匹配

问题:
在一个长度为m的字符串source中,寻找 长度为n的字符串target。如果source字符串中存在target字符串,则返回字符串target第一次在字符串source出现的位置,若不存在,则返回-1。
这里涉及到一个算法–KMP算法
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。
同时,这里也需要了解什么是真前缀和真后缀
举一个例子:
字符串:china
真前缀:c,ch,chi,chin.
真后缀:hina,ina,na,a.
现在就到了上代码的时候
先是暴力算法:(给出重要部分部分)
int Index_1(char s[],int sLen,char p[],int pLen){//s为主串,sLen为主串元素个数,p为模式串,pLen为模式串的个数
if(sLen<pLen)return 0;
int i = 1,j = 1;
while(i<=sLen && j<=pLen){
if(s[i]p[j]){i++;j++;}
else{
i = i-j+2;
j = 1;
}
}
if(j>pLen) return i-pLen;
return 0;
}
接下来就是KMP算法:(有关构建nest数组的部分,有两种)
1.int ne(char a[],int len,int next[])//a是模式串,len是模式串的长度
{
next[1]=0;
int i=1,j=0;
while(i<len){
if(j
0||a[i]==a[j])
next[++i]=++j;
else
j=next[j];
}
}
2.for(int i=2,j=0;i<=n;i++)//p是模式串
{
while(j&&p[i]!=p[j+1])
j=next[j];
if(p[i]==p[j+1])
j++;
next[i]=j;
}
最后给出一完整的代码:(比较特殊)
#include
using namespace std;
const int N=10010,M=100010;
int n,m;
int ne[N];
char s[M],p[N];

int main()
{
cin>>n>>p+1>>m>>s+1;

for(int i=2,j=0;i<=n;i++)
{
while(j&&p[i]!=p[j+1])
j=next[j];
if(p[i]==p[j+1])
j++;
next[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;
j=ne[j];
}
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值