文章网上太多这里提一下代码细节:

KMP:

 scanf("%s\n",s);
scanf("%s\n",t);
int ls=strlen(s),lt=strlen(t);
f[]=f[]=;
for(int i=;i<lt;++i)
{
int j=f[i];
while(j&&t[j]!=t[i]) j=f[j];
if(t[j]==t[i]) f[i+]=j+;else f[i+]=;
}
int j=;
for(int i=;i<ls;++i)
{
while(j&&t[j]!=s[i]) j=f[j];
if(t[j]==s[i]) ++j;
if(j==lt) printf("%d\n",i-lt+);
}//Kmp的代码比较简单理解了就不会出错

扩展KMP:

     scanf("%s\n",s);
scanf("%s\n",t);
int ls=strlen(s),lt=strlen(t);
next[]=lt;
next[]=lt-;//第一个注意点:对自己匹配的时候是要从第1个位置开始暴力,而不是第0个
for(int i=;i<lt-;++i)
if(t[i]!=t[i+])
{
next[]=i;
break;
}
int k=;
for(int i=;i<lt;++i)
{
int p=k+next[k]-,l=next[i-k];
if(i+l<=p) next[i]=l;
else
{
int j=p-i+;
if(j<) j=;//注意这里不加会爆掉而且很难找出来
while(i+j<lt&&t[i+j]==t[j]) ++j;
next[i]=j;
k=i;
}
}
ex[]=lt;//两个串匹配则是从第0个位置开始暴力
for(int i=;i<lt;++i)
if(s[i]!=t[i])
{
ex[]=i;
break;
}
k=;
for(int i=;i<ls;++i)
{
int p=k+ex[k]-,l=next[i-k];
if(i+l<=p) ex[i]=l;
else
{
int j=p-i+;
if(j<) j=;//同上
while(i+j<ls&&j<lt&&s[i+j]==t[j]) ++j;
ex[i]=j;
k=i;
}
}

这里来手推一下扩展Kmp:

设p表示S到达的最远点,而p是由k更新到的,故p=k+ex[k]-1

故s[k..p]==t[0..p-k]

我们要求的是ex[i],所以要找出s[i]开头的一些关系,又注意到i>k,故s[i..p]==t[i-k..p-k]

而又想到应该是s[i..p]==t[0..?],因为匹配的是从0开始的,所以就涉及到了t[i-k..?]和t[0..?]的自身匹配,故引进next[i-k]表示t和t自己匹配(与ex[]一样,只不过ex[]保存的是两个字符串的匹配),设其为L,则有t[i-k..i-k+l-1]==t[0..l-1]

这里考虑:①i-k+l-1<p-k,则说明匹配到的最远的在最远点P之内,故不会涉及到我们不知道的领域,所以肯定ex[i]=l;

     ②i-k+l-1>=p-k,这就说明s[i..p]==t[0..p-i],那么接下来就从s[p+1]和t[p-i+1]开始暴力判断,并维护k和p

KMP和扩展KMP的更多相关文章

  1. KMP和扩展KMP【转】

    这种东西基本上在纸上自己推导一下就能做出来XD 转发注明出处 KMP 给出两个字符串A(称为模板串)和B(称为子串),长度分别为lenA和lenB,要求在线性时间内,对于每个A[i] (0<=i ...

  2. KMP与扩展KMP

    原文转自:http://www.cppblog.com/MatoNo1/archive/2011/04/17/144390.aspx KMP:给出两个字符串A(称为模板串)和B(称为子串),长度分别为 ...

  3. Manacher模板,kmp,扩展kmp,最小表示法模板

    *N]; //储存临时串 *N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); ; ;i<len;i++) { s[cnt++]= ...

  4. KMP && Manacher && 扩展KMP整理

    KMP算法: kmp示例代码: void cal_next(char *str, int *next, int len) { next[0] = -1;//next[0]初始化为-1,-1表示不存在相 ...

  5. kmp模板 && 扩展kmp模板

    kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...

  6. 【kmp或扩展kmp】HDU 6153 A Secret

    acm.hdu.edu.cn/showproblem.php?pid=6153 [题意] 给定字符串A和B,求B的所有后缀在A中出现次数与其长度的乘积之和 A和B的长度最大为1e6 方法一:扩展kmp ...

  7. KMP 、扩展KMP、Manacher算法 总结

    一. KMP 1 找字符串x是否存在于y串中,或者存在了几次 HDU1711 Number Sequence HDU1686 Oulipo HDU2087 剪花布条 2.求多个字符串的最长公共子串 P ...

  8. 666 专题三 KMP &#38; 扩展KMP &#38; Manacher

    KMP: Problem A.Number Sequence d.求子串首次出现在主串中的位置 s. c. #include<iostream> #include<stdio.h&g ...

  9. kmp与扩展kmp模板

    kmp 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include & ...

随机推荐

  1. 03_汇编语言(n个数找最大值)

    程序要求: 先输入一个数n(0<n<=100),再输入n个无符号数K(0<=K<=65535),找出这n个数的最大值并输出 测试实例保证输入每个数之后,都会以回车结束 代码: ...

  2. oracle表连接——处理连接过程中另外一张表没有相关数据不显示问题

    一个数据表基本上很难满足我们的查询要求,同时,将所有的数据都保存在一个表格中显然也不是一种好的数据库设计,为了避免数据的冗余,删除.更新异常,我们通常需要建立一张外键表,通过表连接,来获取我们自己想要 ...

  3. sql date时间加减几天几小时

    //时间转成年月日时分秒select date_format(now(),'%Y%m%d%H%i%S')//时间转成年月日select date_format(now(),'%Y%m%d')//去年此 ...

  4. vs安装mvc

    需要一个MVC框架和SP1补丁包,SP1补丁包的下载地址为:http://www.microsoft.com/downloads/details.aspx?FamilyID=27673c47-b3b5 ...

  5. 【转】${sessionScope.user}的使用方法

    EL 全名为Expression Language EL 语法很简单,它最大的特点就是使用上很方便.接下来介绍EL主要的语法结构: ${sessionScope.user.sex} 所有EL都是以${ ...

  6. smarty变量调节器

    smarty中变量调解器的作用:在模板中需要对PHP分配过来的变量在输出之前,对变量进行处理 注册变量调解器方式:$smarty->registerPlugin("modifier&q ...

  7. f2fs解析(三)NAT中如何区分inode和其他dnode

    首先,我们要知道NAT中的每个表项都对应着MAIN AREA区域中NODE段的一个block,还要知道NODE block很特别,block末尾会有一个node footer结构: 243 struc ...

  8. form表单和ajax表单提交(Html.BeginForm()、Ajax.BeginForm())的差别

    有如下几种区别: 1. Ajax在提交.请求.接收时,都是异步进行的,网页不需要刷新: Form提交则是新建一个页面,哪怕是提交给自己本身的页面,也是需要刷新的: 2. A在提交时,是在后台新建一个请 ...

  9. C# 无边框窗体的最小化问题

    WinForm在窗体风格设置成None时无法最小化的问题.添加以下代码即可实现最小化: protected override CreateParams CreateParams { get { con ...

  10. 静态时序分析(static timing analysis) --- 时序路径

    时序分析工具会找到且分析设计中的所有路径.每一个路径有一个起点(startpoint)和一个终点(endpoint).起点是设计中数据被时钟沿载入的那个时间点,而终点则是数据通过了组合逻辑被另一个时间 ...