很不错的学习链接: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算法模板&&扩展的更多相关文章

  1. hdu 1711 KMP算法模板题

    题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串 ...

  2. kmp算法模板及理解

    kmp算法是复杂度为O(n+m)的字符串匹配算法; 首先kmp算法的核心是在模式串中获得next数组,这个数组表示模式串的子串的前缀和后缀相同的最长长度; 这样在匹配的过程中如果指到不匹配的位置,模式 ...

  3. 【Luogu P3375】字符串匹配KMP算法模板

    Luogu P3375 模式串:即题目中的S2所代表的意义 文本串:即题目中的S1所代表的意义 对于字符串匹配,有一种很显然的朴素算法:在S1中枚举起点一位一位匹配,失配之后起点往后移动一位,从头开始 ...

  4. POJ 3461 Oulipo KMP算法(模板)

    题意: 给两组字符串a和b,求a在b中出现的次数 关于KMP: 马拉车算法是处理回文串,而KMP是处理前后缀的相同字符串的最长长度. a | a | b | a | a | f | a | a 数组 ...

  5. Kmp 算法模板 C

    /** * name:KMP * time:2012-11-22 * 字符串快速匹配 */ #include<stdio.h> #include<string.h> typed ...

  6. KMP算法模板

    不懂的话推荐看这篇博客,讲的很清楚 http://blog.csdn.net/v_july_v/article/details/7041827 #include<iostream> #in ...

  7. KMP算法———模板

    做出KMP字符串匹配算法心情也是好好哒,萌萌哒. 感谢黄学长,感谢栋栋! #include<cstdio>#include<string>#include<iostrea ...

  8. kmp算法 模板

    #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #inclu ...

  9. KMP算法模板(pascal)

    洛谷P3375: program rrr(input,output); var i,j,lena,lenb:longint; a,b:ansistring; next:..]of longint; b ...

随机推荐

  1. ef——存储过程

      数据库中存在存储过程GetCategory: ALTER proc [dbo].[GetCategory] @cid int as begin select * from Categories w ...

  2. 打印插件--PAZU

    PAZU对打印控制实现了: 2.1 设置页眉页脚 2.2 指定纸张大小 2.3 设置纸张方向 2.4 设置页边距 2.5 选择指定的打印机 2.6 无需用户确认,JS直接调用打印预览 2.7 无需用户 ...

  3. asp.netCore连接多个数据库

    1.首先要有对应的context实体类, 多个实体类的构造函数的参数都应该是集合 public class firstContext : DbContext { //多个数据库应该使用这个构造函数,参 ...

  4. 01 使用JavaScript原生控制div属性

    写在前面: 因对前端开发感兴趣,于是自学前端技术,现在已经会HTML.CSS.JavaScript基础技术.但水平处于小白阶段,在网上找一些小项目练练手,促进自己的技术成长.文章记录自己的所思所想,以 ...

  5. java:模拟队列操作

    import java.util.LinkedList; public class Myqueue { private LinkedList<Object> linkedList; pub ...

  6. centos 6无法上外网

    1.先配置/etc/sysconfig/network-scripts/ifcfg-eth0 配置完成后能ping通内网.网关,但是上不了外网 DEVICE=eth0 HWADDR=:0C::FF:: ...

  7. 回顾经典问题算法:LIS, LCS-(DP类别)

    LIS,最长递增子序列说明见:http://blog.csdn.net/sdjzping/article/details/8759870 #include <iostream> #incl ...

  8. CSS实现文字两端对齐

    最近的项目遇到了这样的需求:(要求标题部分不管文字多少,都必须两端对齐) 如下图: 当时也没有多想直接使用‘ ’进行代替,毕竟产品同学想快一点看到效果,不敢怠慢!不过到第二个页面就傻眼了. 如图: 这 ...

  9. JS深拷贝继承

    所谓深拷贝,就是子对象不紧继承父对象的非引用属性,还能继承父对象的引用属性(Object,Array),当子对象对继承的引用类型属性做修改时,父对象的引用类型不会被修改. 我们先写个浅拷贝的封装函数: ...

  10. java线程的常用方法

    java线程的常用方法 编号 方法 说明 1 public void start() 使该线程开始执行:Java 虚拟机调用该线程的 run 方法. 2 public void run() 如果该线程 ...