KMP算法模板&&扩展
很不错的学习链接:https://blog.csdn.net/v_july_v/article/details/7041827
具体思路就看上面的链接就行了,这里只放几个常用的模板
问题描述:
给出字符串a和b,求a中匹配b的所有下标
const int maxn = 1e6 + ;
int Next[maxn];
void Getnext(char* p)//next数组初始化
{
int plen = strlen(p);
Next[] = -;
int k = -, j = ;
while(j < plen - )//next优化 j < plen也可以,只是多求了next[plen]
{
//p[k]表示前缀 p[j]表示后缀
if(k == - || p[j] == p[k])
{
j++, k++;
if(p[j] != p[k])Next[j] = k;
else Next[j] = Next[k];
}
else k = Next[k];
}
/*while(j < plen - 1)//next数组未优化
{
//p[k]表示前缀 p[j]表示后缀
if(k == -1 || p[j] == p[k])
{
j++, k++;
Next[j] = k;
}
else k = Next[k];
}*/
}
int ans;
void KMP(char* s, char* p)//s为文本串,p为匹配串
{
Getnext(p);ans = 0;//ans为匹配次数
int i = , j = ;
int slen = strlen(s), plen = strlen(p);
while(i < slen)
{
if(j == - || s[i] == p[j])
i++, j++;
else j = Next[j];
if(j == plen)//已经匹配
{
ans++;
//cout<<i - j<<endl;//匹配的下标 从0开始
j = next[j];
i--;//如果所匹配的子串之间不可相交,去掉i--;
}
}
}
KMP另一版本:感觉更快
int Next[maxn];
void Getnext(char p[], int plen)//next数组初始化
{
Next[] = ;
int k = ;
for(int i = ; i < plen; i++)
{
while(k > && p[k] != p[i])k = Next[k];
if(p[k] == p[i])k++;
Next[i + ] = k;
}
}
int KMP(char s[], char p[], int slen, int plen)//s为文本串,p为匹配串
{
Getnext(p, plen);//如果匹配串p一直不变,可以在函数外面调用一次即可
int k = ;
int ans = ;
for(int i = ; i < slen; i++)
{
while(k > && p[k] != s[i])k = Next[k];
if(p[k] == s[i])k++;
if(k == plen)
{
ans++;
k = Next[k];//匹配的下标i-j 从0开始
}
}
return ans;
}
KMP算法扩展:
https://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html?from=search
//扩展KMP算法
//求字符串S的后缀 与字符串T的最长公共前缀长度
//extand[i]表示S[i...slen] 与 T的最长公共前缀长度
//Next[i]表示T[i...tlen] 与 T的最长公共前缀长度 也就是最长公共前后缀长度 char s[maxn], t[maxn];
int Next[maxn], extand[maxn];
void Getnext(char t[])//预处理出Next数组
{
int tlen = strlen(t), i = ;
Next[] = tlen;//从0开始的后缀(就是T) 和 T的公共前缀就是T本身
while(i < tlen - && t[i] == t[i + ])i++;
Next[] = i;
int a = ;
for(int i = ; i < tlen; i++)
{
int p = a + Next[a] - , L = Next[i - a];//p为当前匹配到的最远位置,a表示从a开始匹配可以匹配到这个最大位置
if(i - + L >= p)//情况2
{
int j = (p - i + ) > ? (p - i + ) : ;
while(i + j < tlen && t[i + j] == t[j])j++;
Next[i] = j;
a = i;
}
else Next[i] = L;//情况1
}
}
void Getextand(char* s, char* t)
{
memset(Next, , sizeof(Next));
Getnext(t);
int slen = strlen(s), tlen = strlen(t);
int Minlen = Min(slen, tlen);
int a = ;
while(a < Minlen && s[a] == t[a])a++;
extand[] = a;
a = ;
for(int i = ; i < slen; i++)
{
int p = a + extand[a] - , L = Next[i - a];
if(i - + L >= p)//情况2
{
int j = (p - i + ) > ? (p - i + ) : ;
while(i + j < slen && j < tlen && s[i + j] == t[j])j++;
extand[i] = j;
a = i;
}
else extand[i] = L;
}
}
KMP算法模板&&扩展的更多相关文章
- hdu 1711 KMP算法模板题
题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串 ...
- kmp算法模板及理解
kmp算法是复杂度为O(n+m)的字符串匹配算法; 首先kmp算法的核心是在模式串中获得next数组,这个数组表示模式串的子串的前缀和后缀相同的最长长度; 这样在匹配的过程中如果指到不匹配的位置,模式 ...
- 【Luogu P3375】字符串匹配KMP算法模板
Luogu P3375 模式串:即题目中的S2所代表的意义 文本串:即题目中的S1所代表的意义 对于字符串匹配,有一种很显然的朴素算法:在S1中枚举起点一位一位匹配,失配之后起点往后移动一位,从头开始 ...
- POJ 3461 Oulipo KMP算法(模板)
题意: 给两组字符串a和b,求a在b中出现的次数 关于KMP: 马拉车算法是处理回文串,而KMP是处理前后缀的相同字符串的最长长度. a | a | b | a | a | f | a | a 数组 ...
- Kmp 算法模板 C
/** * name:KMP * time:2012-11-22 * 字符串快速匹配 */ #include<stdio.h> #include<string.h> typed ...
- KMP算法模板
不懂的话推荐看这篇博客,讲的很清楚 http://blog.csdn.net/v_july_v/article/details/7041827 #include<iostream> #in ...
- KMP算法———模板
做出KMP字符串匹配算法心情也是好好哒,萌萌哒. 感谢黄学长,感谢栋栋! #include<cstdio>#include<string>#include<iostrea ...
- kmp算法 模板
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #inclu ...
- KMP算法模板(pascal)
洛谷P3375: program rrr(input,output); var i,j,lena,lenb:longint; a,b:ansistring; next:..]of longint; b ...
随机推荐
- Delphi下OpenGL2d绘图(06)-画图(多窗口、多视图、多个DC)
一.前言 在学习OpenGL的过程中,发现很多函数都是全局的.前面几章中都是在一个窗口DC中画图,那么要在多个窗口画图,需要怎么处理呢?网上方法有多种,这里采用其中一种,利用wglMakeCurren ...
- Fanvas是一个把swf转为html5 canvas动画的系统
https://github.com/Tencent/Fanvas 使用方法: 代码: <!DOCTYPE html> <html> <head> ...
- vmware8~12最新版本 克隆Centos6.X 系列虚拟机网卡无法启动问题 (三步即可)
1.因工作或者学习需要,都需要在VM上克隆一台服务器,此时无论是快捷克隆(相当于快照的机体)或者完整克隆,都会碰到IP问题. 如:创建后症状:启动之后使用ifconfig,发现无ip地址,只有回环地址 ...
- BTREE索引和HASH索引的区别
从本质上理解,BTREE是一种有序树,而hash是无序的.所以最关键的区别在于: 1,BTREE可以用来做范围查询,比如大于,小于,而HASH索引仅在"=","IN&qu ...
- jquery里判断数组内是否包含了指定的值或元素的方法
本文讲的是在jquery里,如何判断一个数组里是否包含了指定的值,变量,或其它对象元素的方法. 在jquery里,我们可以用$.inArray来判断一个数组里是否包含了指定的值或其它对象元素,来看一个 ...
- IIS利用X-Forwarded-For获得来访者的真实IP
https://help.aliyun.com/knowledge_detail/37948.html
- Java学习--使用 Math 类操作数据
使用 Math 类操作数据 Math 类位于 java.lang 包中,包含用于执行基本数学运算的方法, Math 类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名,如: M ...
- 在IIS中部署好WCF服务站点后,本机访问服务无问题,局域网中其他电脑访问不到
1.问题描述 在IIS中部署好WCF服务站点后,本机访问服务无问题,局域网中其他电脑访问不到. 2.解决方法 (1)控制面板 -> Windows防火墙 -> 高级设置 (2)属性 (3) ...
- LintCode2016年8月22日算法比赛----将数组重新排序以构造最小值
将数组重新排序以构造最小值 题目描述 给定一个整数数组,请将其重新排序,以构造最小值. 样例 给定[3,32,321],通过将数组重新排序,可构造6个可能性的数字: 3+32+321=332321 3 ...
- Storm-Concept
1. Storm集群架构 strom jar all-your-code.jar backtype.storm.MyWordCounterTopology arg1 arg2 这个命 ...