很不错的学习链接: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. 选择适用才最好 盘点MySQL备份方式

    我们要备份什么? 一般情况下, 我们需要备份的数据分为以下几种 数据 二进制日志, InnoDB事务日志 代码(存储过程.存储函数.触发器.事件调度器) 服务器配置文件 备份工具 这里我们列举出常用的 ...

  2. Axios的详细配置和相关使用

    Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. Features 从浏览器中创建 XMLHttpRequests 从 node.js 创建 http  ...

  3. 撩课-Web大前端每天5道面试题-Day4

    1. 如何实现瀑布流? 瀑布流布局的原理: ) 瀑布流布局要求要进行布置的元素等宽, 然后计算元素的宽度, 与浏览器宽度之比,得到需要布置的列数; ) 创建一个数组,长度为列数, 里面的值为已布置元素 ...

  4. [LeetCode]Longest Palindromic Substring题解(动态规划)

    Longest Palindromic Substring: Given a string s, find the longest palindromic substring in s. You ma ...

  5. I/O概述

    同步:同步等待,按照顺序执行,单线程.异步:异步并发,多线程. 阻塞:请求一个操作,如果条件不满足,一直等待需要的条件,直到条件满足.非阻塞:请求一个操作,如果条件不满足,则返回不满足条件的标志信息. ...

  6. IAAS,SAAS,PAAS, CaaS的区别

    来源:云计算头条微信公众号  作者:   你一定听说过云计算中的三个“高大上”的你一定听说过云计算中的三个“高大上”的概念:IaaS.PaaS和SaaS,这几个术语并不好理解.不过,如果你是个吃货,还 ...

  7. 解决Fiddler无法捕获本地HttpWebRequest(C#.net)请求和HttpURLConnection(Java)请求

    方法很简单,就是设置本地代理 C# HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.Proxy = new WebPr ...

  8. 使用装饰器减少try ...finally的重复使用

    @util.try_except_bskgk def added_user_handle(cur, search_time): added_user_sql = """ ...

  9. Sublime Text3之安裝Emmet及使用技巧

    首先准备工作: 如果你的Sublime Text3没有Package Control组件先看一下这里,如果以安装请忽略: 1.按Ctrl+`调出sublime text的console 2.粘贴以下代 ...

  10. How To Install Cacti On Ubuntu 14

    How To Install Cacti On Ubuntu 14.04/14.10 by anismaj Cacti is an open source web based network moni ...