kmp

[kmp,不要过多调用strlen!!!] Codeforces 1200E Compress Words

匿名 (未验证) 提交于 2019-12-02 23:55:01
题目: http://codeforces.com/contest/1200/problem/E Compress Words time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output n sample" and " please" into " samplease". Amugae will merge his sentence left to right (i.e. first merge the first two words, then merge the result with the third word and so on). Write a program that prints the compressed word after the merging process ends. Input n 1 ≤ n ≤ 10 5 1≤n≤105), the number of the words in Amugae's sentence. n A', ' B', ..., ' Z', ' a', ' b', ..., ' z', ' 0', ' 1', ..., ' 10 6 106. Output In the

关于KMP学习笔记//2019/7/26

匿名 (未验证) 提交于 2019-12-02 23:52:01
网上一堆“形象”博客浪费我一堆时间,果然以前摸的鱼现在还得还 QAQ 我来讲我对于KMP算法的自己理解 首先声明一下,KMP算法最关键的地方不在于匹配,而在于求模式串的最长匹配前后缀, 在网上的其他博客上,这个“最长匹配前后缀”的名字被替换成了“nxt”,而导致博客十分的“好懂” wdnmd我怎么知道nxt是什么 想一想求一个字符串最长匹配前后缀的最差复杂度是多少?$O(n)$? 是$O(n^2)$啊带哥,枚举长度$O(n)$,判断是否匹配$O(n)$,简直烂到爆 而KMP算法是求出一个字符串$\S$,以位置$\i$为尾的最长匹配前后缀$(1<=i<=strlen(S))$ 复杂度难以置信的是$\O(nlogn)$,肥肠优秀,而且不是很难学 KMP最关键代码如下 //b[i]是模式串,nxt数组就是最长匹配前后缀长度 void make_nxt(){ int j=0; for(int i=2;i<=lenb;i++){ while(b[j+1] != b[i] && j>0) j=nxt[j]; if(b[j+1] == b[i]) nxt[i] = ++j; else nxt[i] = 0; } return ; } 一边看一边说,主要的是, j是当前位的最长匹配前后缀长度 ,将j维护好之后,赋值给nxt就好 现在的问题就是怎么维护j了, 刚开始到达这一位的时候

字符串模板--KMP

匿名 (未验证) 提交于 2019-12-02 23:51:01
1 void getnext() 2 { 3 int k=-1,i=0; 4 nxt[0]=-1; 5 while(i<lent){ 6 while(k>=0&&t[k]!=t[i]) 7 k=nxt[k]; 8 i++,k++; 9 nxt[i]=k; 10 } 11 } 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define e exit(0) 6 #define R register 7 const int maxn=1e6+10; 8 char s[maxn],t[maxn]; 9 int lens,lent,deep,nxt[maxn],pos[maxn]; 10 void getnext() 11 { 12 int k=-1,i=0; 13 nxt[0]=-1; 14 while(i<lent){ 15 while(k>=0&&t[k]!=t[i]) 16 k=nxt[k]; 17 i++,k++; 18 nxt[i]=k; 19 } 20 } 21 void kmp() 22 { 23 int i=0,j=0; 24 while(j<lens){ 25 while(i>=0&&t[i]!=s[j]) 26 i=nxt[i]; 27 i++

数据结构――KMP算法

匿名 (未验证) 提交于 2019-12-02 23:49:02
算法介绍    KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特―莫里斯―普拉特操作(简称KMP算法)。KMP算法的核心是 利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的 。具体实现就是通过一个 next()函数 实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。 next数组   我们记主串为字符串S,模式串为字符串P。   我们用next[j]表示 以字符Pj结尾 的子串的 长度相等的前缀字符串与后缀字符串长度的最大值 。   为了方便起见,我们将字符串从下标1开始匹配。如此,next数组所表示的长度就与下标数值相等了。 算法思路   我们从左到右依次枚举S的每一个字符Si,对于当前待匹配字符Si,我们假设当前P字符串中已匹配到Pj。   那么我们只需判断Si和Pj+1,若两者相同,则继续匹配。   若两者不相同,那么我们使j=next[j],即可最大限度的减少匹配次数。因为S字符串的从某位置开始到前i-1的部分与P字符串的前j个字符已匹配(即完全相同),而P1到Pnext[j]部分是长度最大的与以Pj结尾的后缀完全相同的前缀,而该以Pj结尾的后缀则必定与S中一段以Si-1结尾的子串完全相同,因而保证了上述操作的正确性。  

【KMP】Radio Transmission

匿名 (未验证) 提交于 2019-12-02 23:49:02
题目描述 给你一个字符串,它是由某个字符串不断自我连接形成的。但是这个字符串是不确定的,现在只想知道它的最短长度是多少。 输入 第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成. 输出 请输出最短的长度 样例输入 8 cabcabca 样例输出 3 题解 #include<iostream> #include<cstring> using namespace std; int n,q[1000005]; char a[1000005]; int main() { cin>>n; scanf("%s",a+1); int j=0; q[1]=0; for(int i=2;i<=n;i++) { while(j&&a[i]!=a[j+1]) j=q[j]; if(a[i]==a[j+1]) j++; q[i]=j; } cout<<n-q[n]<<endl; return 0; } 文章来源: https://blog.csdn.net/weixin_42146061/article/details/96850356

KMP入门

匿名 (未验证) 提交于 2019-12-02 23:49:02
#include <iostream> #include <cstring> using namespace std ; char s [ 1000 ], p [ 1000 ]; inline int getans ( char * s , char * p ){ int sl = strlen ( s ), pl = strlen ( p ); int i = 0 , j = 0 ; while ( i < sl && j < pl ){ if ( s [ i ]== p [ j ]) i ++, j ++; else { i = i - j + 1 ; j = 0 ; } } if ( j == pl ) return i - j ; else return - 1 ; } int main (){ cin >> s >> p ; int ans = getans ( s , p ); cout << ans << endl ; return 0 ; } inline int KMPsearch ( char * s , char * p ){ int sl = strlen ( s ), pl = strlen ( p ); int i = 0 , j = 0 ; while ( i < sl && j < pl ){ if ( s [ i ]== p [ j ]|| j =

KMP

匿名 (未验证) 提交于 2019-12-02 23:32:01
KMP学了好几遍了,今天才明白的差不多... 留篇博客,免得自己以后忘了qaq 我们先讨论next的含义: next[i] : 在0<=j<i中的最大的j,满足0-i中,使长度为j的后缀和长度为j的前缀相同 接下来我们讨论两个问题:1.怎么求next; 2.有了next怎么求匹配 定义:next[1] = 0(由定义),next[0]不定义,默认为0 问题1:怎么求next 考虑目前到i + 1,令j=next[i],那么如果a[j + 1] != a[i + 1],说明此时的next[i]的下一位与a[i + 1]不等,即next[i + 1] != next[i] + 1了 那么和0-i的这一段后缀相等的最大前缀只能是next[j]即next[next[i]],那么令j=next[j],继续进行上述判断,直到j=0无法判断为止 问题2:有了next怎么求匹配 考虑目前匹配到模版串的j,原串的i,如果a[j] == a[i],自然这一位相等,令j++ 否则,已经匹配的一段j中,有一部分和原串之前匹配的部分是相等的,这个位置就是next[j](显然的由next的定义,这个长度是合法且极大的) 这样问题就可以解决了 考虑kmp的复杂度,在问题2中,我们至多只令j增加n次,而虽然在令j=next[j]的过程中可能有多次运算,但可以通过势能分析证明 我们将j=next[j

[学习笔记] kmp

一世执手 提交于 2019-12-02 12:43:32
不知道开头写什么话 康康下面这个问题: 给定一个模式串和一个文本串,求模式串在文本串中出现的位置,次数. 一个显然的做法是对于文本串中的每个位置,都把模式串从头开始匹配. 但是这样的时间复杂度太高了, 所以我们有了接下来要讲的: kmp算法 . step 0 先定义一些东西. \(a\) :模式串. \(b\) :文本串. \(la\) : \(a\) 的长度. \(lb\) : \(b\) 的长度. \(next[i]\) :模式串中满足 \(a[1\sim j]=a[i-j+1\sim i]\) 的最大的 \(j\) . \(f[i]\) :满足 \(a[1\sim j]=b[i-j+1\sim i]\) 的最大的 \(j\) . step 1 首先暴力的算法因为时间复杂度太高( \(O(la*lb)\) )而被抛弃... 所以我们要想想怎么排除掉一些多余的情况. 先举个例子: \(a\) :bababb. \(b\) :bababababababababb. 我们在第一次匹配的时候会是这样: babab |b babab |ababababababb 在第六位的时候失配了.. 但是我们可以发现,前五位的 \(f[i]\) 都已经求出来了. 如果我们采取暴力的做法,将 \(a\) 直接往后移一位时,就是这样: |bababb b|ababababababababb

KMP算法---私人笔记

送分小仙女□ 提交于 2019-12-02 11:37:38
  先给出模式匹配问题:给出两个字符穿,一个为S(主串)另一个为T(字串),模式匹配就是求T在S中的位置。我们先介绍简单的模式匹配算法,KMP算法是基于这种算法的改进算法。   简单的模式匹配算法:从S的第一个字符开始和T的第一个字符进行比较,若相等,则继续逐个的比较后续的字符,直到T中的每个字符依次和S中的一个连续的字符序列相等,则匹配成功,返回这个S中的连续字符序列的第一个字符的下标,如果在比较过程中有某个字符不相等,则从S 的下一个字符开始重新和T的第一个字符比较,依此类推,直到S中的字符都比较完了仍然没有匹配成功的话,则匹配不成功。Python实现代码如下: def StrMatching(S,T): i,j=0,0 m,n=len(S),len(T) while i<m and j<n: if S[i]==T[j]: i+=1 j+=1 else: i=i-j+1 j=0 if j==n: return i-n   else: return 0   KMP算法:   接下来进入我们的正餐KMP算法,上述的简单的模式匹配算法的最坏的时间复杂度为O(n*m),KMP算法可以在(m+n)的时间数量级上完成模式匹配操作。KMP算法的改进在于:每当一趟匹配过程中出现字符不相等时,不需要回溯i指针,而是利用已经得到的"部分匹配"的结果将模式串T向右"滑动"尽可能远的一段距离后

AcWing 831 KMP字符串

岁酱吖の 提交于 2019-12-02 07:05:01
给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。 模板串P在模式串S中多次作为子串出现。 求出模板串P在模式串S中所有出现的位置的起始下标。 输入格式 第一行输入整数N,表示字符串P的长度。 第二行输入字符串P。 第三行输入整数M,表示字符串S的长度。 第四行输入字符串M。 输出格式 共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。 数据范围 1≤N≤104 1≤M≤105 输入样例 3 aba 5 ababa KMP算法求字符串匹配。文本串为S,匹配串为P,不难想到暴力做法,即从S和P的第一个字符开始,逐一比对,如果二者相同,那么S和P都前进到下一个字符,如果不相同,那么S回退到第一个字符之后的一个字符,作为新的比对起点,而P回退到第一个字符。 KMP算法的思想在于,同样是逐一比对,但当遇到不相同字符时,S串的指针不回退,而P串的指针不必回退到第一个字符,而是 j = next[j] (假设 j 是模式串P的指针)。 举例: 文本串S:...REGR E T... 匹配串P: REGR O W 这里 E 和 O 不匹配,保持文本串S的指针i不变,将匹配串指针j移动到 next[j] 文本串S:...REGR E T... 匹配串P:    R E GROW 所以 next[] 数组的意义就是利用匹配串自身的信息-