KMP算法入门
学一把看毛片算法我觉得自己才能变得更加出色
明明昨天的题我都知道怎么模拟了,但是还是不会改KMP,是我学丑了
KMP是Knuth-Morris-Pratt三人设计的线性时间字符串匹配算法
nxt数组的介绍,卧槽,直接找到太爽啦


就是我匹配的时候是可以回退的,因为字符的肯能性有限
比如aaaaaaaaab和aaaab进行匹配,aaaab是模式串,aaaaaaaaab是匹配串,我就不用回退那么多次数,因为及时往下推就好了
我匹配了一部分我就能回退到一定的位置
下面是一段演示
我用的求前缀函数
void pre(char *p)
{
int i,m,j;
m=strlen(p+1);
nex[]=nex[]=;
for(int i=; i<m; i++)
{
j=nex[i];
while(j&&p[i]!=p[j])j=nex[j];
nex[i+]=p[i]==p[j]?j+:;
}
}
aaaab
0 0 1 2 3
aba
0 0 0
就是在字符串匹配时可以回退,因为这些字符和前缀是相同的,所以直接回退就可以的

匹配不成功得到的j值
换一组数据

直接匹配就没有回退了


解释下这个复杂些的,就是我往下走啊,但是但匹配到模式串5发现不能继续了,还有两次到2就不能继续了,窝看看nxt可不可以少做些
用来测试的代码
#include <bits/stdc++.h>
using namespace std;
const int N=;
char s[N],t[N];
int nxt[N],sum[N];
void pre(char *p)
{
int i,m,j;
m=strlen(p+);
nxt[]=nxt[]=;
for(int i=; i<m; i++)
{
j=nxt[i];
while(j&&p[i]!=p[j])j=nxt[j];
nxt[i+]=p[i]==p[j]?j+:;
}
}
void KMP(char *a,char *b){
pre(b);
int j=;
int len1=strlen(a+);
int len2=strlen(b+);
for(int i=;i<=len1;i++){
while(j&&a[i]!=b[j+])
{printf("%d ",j);j=nxt[j];}
if(a[i]==b[j+]) j++;
if(j==len2){
printf("\na[%d~%d]==b\n",i-len2+,i);
j=nxt[j];
}
}
}
int main()
{
scanf("%s",s+);
scanf("%s",t+);
KMP(s,t);
return ;
}
我的模板
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+;
char s[N],t[N];
int nxt[N];
void pre(char *t)
{
int i=,j=-;
nxt[]=-;
while(t[i])
{
if(j==-||t[i]==t[j])
{
i++,j++;
if(t[i]!=t[j])nxt[i]=j;
else nxt[i]=nxt[j];
}
else j=nxt[j];
}
}
int KMP(char *s,char *t)
{
pre(t);
int i=,j=;
while(s[i])
{
if(j==-||s[i]==t[j])i++,j++;
else j=nxt[j];
}
return j;
}
int main()
{ return ;
}
伪代码
KMP-MATCHER(T, P)
1 n ← length[T]
2 m ← length[P]
3 π ← COMPUTE-PREFIX-FUNCTION(P)
4 q ← 0 ▹Number of characters matched.
5 for i ← 1 to n ▹Scan the text from left to right.
6 do while q > 0 and P[q + 1] ≠ T[i]
7 do q ← π[q] ▹Next character does not match.
8 if P[q + 1] = T[i]
9 then q ← q + 1 ▹Next character matches.
10 if q = m ▹Is all of P matched?
11 then print "Pattern occurs with shift" i - m
12 q ← π[q] ▹Look for the next match.
COMPUTE-PREFIX-FUNCTION(P)
1 m ← length[P]
2 π[1] ← 0
3 k ← 0
4 for q ← 2 to m
5 do while k > 0 and P[k + 1] ≠ P[q]
6 do k ← π[k]
7 if P[k + 1] = P[q]
8 then k ← k + 1
9 π[q] ← k
10 return π
KMP算法入门的更多相关文章
- 【面向打野编程】——KMP算法入门
一.问题 咱们先不管什么KMP,来看看怎么匹配两个字符串. 问题:给定两个字符串,求第二个字符串是否包含于第一个字符串中. 为了具体化,我们以 ABCAXABCABCABX 与 ABCABCABX为例 ...
- 【初识】KMP算法入门(转)
感觉写的很好,尤其是底下的公式,易懂,链接:http://www.cnblogs.com/mypride/p/4950245.html 举个例子 模式串S:a s d a s d a s d f a ...
- 【初识】KMP算法入门
举个例子 模式串S:a s d a s d a s d f a s d 匹配串T:a s d a s d f 如果使用朴素匹配算法—— 1 2 3 4 5 6 8 9 a s d a s d a s ...
- KMP算法入门讲解
字符串匹配问题.假设文本是一个长度为$n$的字符串$T$,模板是一个长度为$m$的字符串$P$,且$m\leq n$.需要求出模板在文本中的所有匹配点$i$,即满足$T[i]=P[0],T[I+1]= ...
- KMP算法——从入门到懵逼到了解
本博文參考http://blog.csdn.net/v_july_v/article/details/7041827 关于其它字符串匹配算法见http://blog.csdn.net/WINCOL/a ...
- KMP算法之从懵逼到入门
写本文的目的: 1.加深自己的理解,以便自己日后复习 2.给看到此文的人一点启发 KMP算法看懂了就觉得特别简单,思路也好理解,但是看不懂之前,查各种资料看大佬的博客,都很懵逼...... 1. 算 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- KMP算法的Next数组详解
转载请注明来源,并包含相关链接. 网上有很多讲解KMP算法的博客,我就不浪费时间再写一份了.直接推荐一个当初我入门时看的博客吧:http://www.cnblogs.com/yjiyjige/p/32 ...
- 【转】KMP算法
转载请注明来源,并包含相关链接.http://www.cnblogs.com/yjiyjige/p/3263858.html 网上有很多讲解KMP算法的博客,我就不浪费时间再写一份了.直接推荐一个当初 ...
随机推荐
- MySql自动默认时间及更新时间
注意:5.7 才能用类型为datetime的字段实现 `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `modifie ...
- hdfs校验和
hdfs完整性:用户希望储存和处理数据的时候,不会有任何损失或者损坏.所以提供了两种校验: 1.校验和(常用循环冗余校验CRC-32). 2.运行后台进程来检测数据块. 校验和: a.写入数据节点验证 ...
- Microsoft Exchange本地和Exchange Online可以与第三方服务共享
很多人都知道Office 365中的Microsoft Exchange本地和Exchange Online可以与第三方服务共享您的个人数据?例如,在Exchange电子邮件中找到的任何地图地址都会发 ...
- OpenLayers 3 的 图层控制控件
openlayers3的control中没有提供默认的图层控制控件. 但是git上已经有造好的轮子,直接拿来用就可以了.地址 https://github.com/walkermatt/ol3-lay ...
- Android(java)学习笔记119:BroadcastReceiver之 短信发送的广播接收者
有时候,我们需要开发出来一个短信监听器,监听用户发送的短信记录,下面就是一个案例,这里同样需要使用广播机制. 下面同样是代码示例,MainActivity.java 和 activity_main. ...
- Linux 备份
备份之前的准备工作 安装常用的软件 常用软件的安装,见我另一篇blog Ubuntu 16.04 安装札记 的第四部分. 清理系统中没用的垃圾 至于垃圾清理,主要清理对象有 sudo rm -r ~/ ...
- Python-OpenCV中的filter2D()函数
使用自定义内核对图像进行卷积.该功能将任意线性滤波器应用于图像.支持就地操作.当光圈部分位于图像外部时,该功能会根据指定的边框模式插入异常像素值. 语法 函数原型: dst=cv.filter2D(s ...
- laydate时间控件绑定回调事件
onclick="laydate({istime: true, format: 'YYYY-MM-DD',choose:checkDate});" //回调函数内容 functio ...
- *运算和&运算
/* &:取地址运算符 *:指针运算符(或称为间接运算符),取指针所指向的对象的内容 */ int a,b; int *pointer_1, *pointer_2; pointer_1 = & ...
- Centos7系统下安装Docker
1.确定你的Linux系统是Centos7 命令:cat /etc/redhat-release 2.yum安装gcc相关 1.配置好Centos7能上外网. 2.yum -y install gcc ...