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算法的博客,我就不浪费时间再写一份了.直接推荐一个当初 ...
随机推荐
- Jenkins系列——使用Dashboard View分类展示作业
1.目标 创建的作业多了,在一个视图中展示多有不便.因此需要使用 Dashboard View 将作业按照后缀进行分类展示. 如下图,可以按照后缀添加CODE,TEST和OTHER视图. 2.环境说明 ...
- Countup.js:vue-countup-v2(npm)数字滚动插件
1.官方地址:http://inorganik.github.io/countUp.js/ 2.官方demo: 3.参数说明: params——start(开始数字).end(结束数字).decima ...
- 51nod 1693 水群
基准时间限制:0.4 秒 空间限制:524288 KB 分值: 160 难度:6级算法题 收藏 关注 总所周知,水群是一件很浪费时间的事,但是其实在水群这件事中,也可以找到一些有意思的东西. 比如 ...
- UVA 1608 Non-boring sequence 不无聊的序列(分治,中途相遇)
题意:给你一个长度为n序列,如果这个任意连续子序列的中都有至少出现一次的元素,那么就称这个序列是不无聊的,判断这个序列是不是无聊的. 先预处理出每个元素之前和之后相同元素出现的位置,就可以在O(1)的 ...
- opencv中mat的type
type表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数),由type()返回,但是返回值是int型,不是OpenCV预定义的宏( ...
- Paper: 《Bert》
Bert: Bidirectional Encoder Representations from Transformers. 主要创新点:Masked LM 和 Next sentence predi ...
- Python面向对象(三)
类的使用:实例化.属性引用 实例化 g1 = Garen('草丛伦1') # 实例化 g2 = Garen('草丛伦2') g3 = Garen('草丛伦3') 类的属性:变量和函数 print(Ga ...
- 使用jsp读取某个目录下的所有文件名,并保存在json文件中
<%@page import="java.io.File"%> <%@page import="java.io.FileWriter"%> ...
- cocos2d-x的基本动作2
1.基本动作 Cocos2d提供的基本动作:瞬时动作.延时动作.运作速度. 瞬时动作:就是不需要时间,马上就完成的动作.瞬时动作的共同基类是 InstantAction. Cocos2d提供以下瞬时动 ...
- #ifdef #else #endif #fi #ifndef 的用法
预处理就是在进行编译的第一遍词法扫描和语法分析之前所作的工作.说白了,就是对源文件进行编译前,先对预处理部分进行处理,然后对处理后的代码进行编译.这样做的好处是,经过处理后的代码,将会变的很精短. ...