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 ...
随机推荐
- 使用T-SQL语句创建数据库2
创建多个数据文件和多个日志文件 use master GO create database book on primaty --主文件组 ( name=‘book_data’, --主文件逻辑文件名 ...
- 文件流FileStram类
本节课主要学习三个内容: 创建FileStram流 读取流 写入流 文件流FileStram类,是用来实现对文件的读取和写入.FileStram是操作字节的字节数组,当提供向文件读取和写入字节的方法时 ...
- [C语言] 数据结构-预备知识指针
所有的伟大源于一个勇敢的开始 数据结构预备知识 指针 1.指针:是C语言的灵魂,指针=地址 地址:内存单元的编号 指针变量:存放内存单元地址的变量 int *p;//p是指针变量,int *表示该p变 ...
- Java基础教程(3)--回顾HelloWorld
在上一篇文章中,我们已经编写了第一个Java程序--HelloWorld,并且对它进行了编译和运行.虽然这个例子很短小,但是它具有一个完整的Java程序所应该具有的结构.在这篇文章中,我将会对这个 ...
- Springboot简介01
前言: spring是近几年java中最具有代表而且最为流行的框架,spring是基于aop和IOC的思想,在我们的项目中充当了一个粘合剂的作用,既可以成为对象工厂,来管理我们的controller. ...
- jQuery中判断input的checked属性
<input type="checkbox" id="ipt1" checked> <input type="checkbox&qu ...
- CSS使用小技巧
对于元素position 属性中的 relative absolute 页面居中问题 /* relative */div{ position:relative; margin: 0 auto}/* ...
- drupal7 自定义登录&找回密码页面,注意事项
1.登录页面的 $form['form_id'] 和 $form['form_build_id'],是这样输出的: <?php print drupal_render($form['form_i ...
- DOM操作表单(select下拉选框)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- FormData js对象的介绍和使用
FormData js对象的介绍和使用 FormData对象,可以把所有表单元素的name与value组成一个queryString,提交到后台. 在使用ajax提交时,使用FormData对象可以减 ...