kmp

KMP

若如初见. 提交于 2019-11-29 09:49:37
KMP字符串匹配 #include <bits/stdc++.h> using namespace std; const int N=10005; int next1[1005]; void getnext1(string s) { int i=0/*起始下标*/,j=-1;//起始下标-1 next1[0]=-1; while(i<s.length()-1) //next[i]=当前字符前的子串的前缀和后缀有几个字符相等再加上数组的起始下标 { // cout<<i<<" "<<j<<endl; if(j==-1||s[i]==s[j]) { ++i; ++j; next1[i]=j; } else j=next1[j]; } } void getnext2(string s) //改进next数组 { int i=0,j=-1; next1[0]=-1; while(i<s.length()-1) { // cout<<i<<" "<<j<<endl; if(j==-1||s[i]==s[j]) { ++i; ++j; if(s[i]!=s[j]) //如果s[i]==s[next1[i]]->next[i]=next[nextp[i] next1[i]=j; else next1[i]=next1[j]; } else j=next1[j]; } } int kmp

Oulipo POJ - 3461 (kmp模板)

懵懂的女人 提交于 2019-11-29 09:48:40
The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quote from the book: Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où s’abolissait la raison : tout avait l

2019 Xuzhou D. Carneginon(kmp / stl - string)

强颜欢笑 提交于 2019-11-29 08:21:20
链接: https://nanti.jisuanke.com/t/41386 来源:The Preliminary Contest for ICPC Asia Xuzhou 2019   题意:给我们两个字符串 t s,1. lent == lens:t == s 输出 jntm! 否则输出 friend! 2. lent > lens s 是 t 的子串 输出 my child! 否则输出 oh, child! 3. lent ≤ lens t 是 s 的子串 输出 my teacher! 否则输出 senior! //stl - string # include <bits/stdc++.h> using namespace std ; int main ( ) { ios : : sync_with_stdio ( false ) ; string t ; int q ; cin >> t >> q ; int lent = t . length ( ) ; while ( q -- ) { string s ; cin >> s ; int lens = s . length ( ) ; if ( lens == lent ) { if ( s == t ) cout << "jntm!" << '\n' ; else cout << "friend!" << '\n' ;

【字符串】KMP

十年热恋 提交于 2019-11-29 05:27:00
Algorithm Task 给定一个文本串 \(S\) 和一个模式串 \(T\) ,求 \(T\) 在 \(S\) 中出现的所有位置。 Limitations 要求时空复杂度均为线性。 Solution 回头重新学一遍 看毛片 KMP 算法。 设 \(X\) 是一个字符串,则以下表述中, \(X_u\) 代表 \(X\) 的第 \(u\) 个字符, \(X_{u \sim v}\) 代表 \(X\) 的从 \(u\) 起到 \(v\) 结束的字串。 首先定义一个字符串的公共前后缀为这个字符串的一个 \(border\) ,最长公共前后缀称为最长 \(border\) 。特别的,不认为字符串本身是自身的 \(border\) 。 性质:字符串 \(S\) 的 \(border\) 的 \(border\) 一定是 \(S\) 的 \(border\) ,正确性显然。因此不断地跳最长 \(border\) 可以遍历字符串的所有 \(border\) 例如,对于字符串 \(abaab\) 来说,其唯一的 \(border\) 是 \(ab\) 。 暴力匹配两个字符串,时间复杂度为 \(O(|S||T|)\) ,考虑优化这个算法。 假设当前匹配时 \(S\) 扫描到了第 \(i\) 位, \(T\) 扫描到了第 \(j\) 位,且 \(S\) 从 \(i\) 向前 \(j\)

126B Password[扩展kmp学习]

允我心安 提交于 2019-11-29 03:11:23
题目大意 给你一个字符串,求它的一个子串使得这个子串即使前缀又是后缀又出现在不是前缀且不是后缀的地方 分析 扩展kmp就是定义z[i]表示i~n的子串与整个串的最长公共前缀的长度是z[i] 所以这个题就是找到一个位置使得z[i]=n-i+1 这样保证了是前缀和后缀 然后再判断之前是否有一个z[j]=z[i] 有的话代表这个长度的串在中间也出现过 直接输出这个即可 代码 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cctype> #include<cmath> #include<cstdlib> #include<queue> #include<ctime> #include<vector> #include<set> #include<map> #include<stack> using namespace std; char s[1000100]; int n,z[1000100],mx; inline void get_z(){ int i,j,k,l=0,r=0; for(i=1;i<n;i++){ if(i<=r)z[i]=min(r-i+1,z[i-l]); while(i+z[i]<n&&s[z[i]]==s[i+z

Count the string[KMP]HDU3336

安稳与你 提交于 2019-11-28 22:49:57
题库链接 http://acm.hdu.edu.cn/showproblem.php?pid=3336     这道题是KMP的next数组的一个简单使用,首先要理解next数组的现实意义:next[i]表示模式串的前i个字符所组成的字符串的最长前缀后缀匹配长度,就比如对于字符串"abcdabe",它的next[3]=0,因为前三个字符构成的字符子串"abc"前后缀最长匹配长度为0,而next[6]=2,因为对于子串"abcdab",它的前缀后缀最大可以匹配出"ab",长度为2,对应了它的前缀后缀最大匹配长度。   对于这道题,我们从1位置开始遍历整个next数组,首先每一个前缀串自身都对答案有1的贡献,所以首先ans++,此外,当与到next[i]数值大于0的位置,说明前i个字符组成的子串有大于零的前缀后缀匹配,即前缀串在该位置重复出现了一次,所以此时ans再加1。  详见代码: #include<bits/stdc++.h> using namespace std; char s[200010]; int t,n,nex[200010]; int ans; void getNex(){ nex[0]=-1; int k=-1,j=0; while(j<n){ if(k==-1||s[j]==s[k]){ ++j;++k; nex[j]=k; } else k=nex[k]; }

KMP字符串 AcWing 831

别等时光非礼了梦想. 提交于 2019-11-28 20:34:53
题目:https://www.acwing.com/problem/content/833/ 题意:求子串在母串中每次出现时的下标位置。 题解:哈哈哈,敲题时想到之前看到一个人叫 kmp 算法为 看毛片 算法,真是笑死我了hiahiahiahiahia。^ 。 该题的出现位置有点像暴力,跟循环节相关的题略有不同,在使用kmp的时候当与子串成功匹配时 j 的变化要注意,还有怎样输出下标。 代码: 1 #include <map> 2 #include <stack> 3 #include <queue> 4 #include <cmath> 5 #include <string> 6 #include <limits> 7 #include <cstdio> 8 #include <vector> 9 #include <cstdlib> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 #define Scc(c) scanf("%c",&c) 14 #define Scs(s) scanf("%s",s) 15 #define Sci(x) scanf("%d",&x) 16 #define Sci2(x, y) scanf("%d%d",&x,&y) 17 #define Sci3(x

洛谷P5410 拓展KMP 模板题

流过昼夜 提交于 2019-11-28 19:31:36
洛谷P5410 拓展KMP 模板题 KMP算法大家应该都知道,拓展KMP顾名思义,就是在KMP算法上面的扩展和加难。 拓展KMP的经典题型就是:给你两个串,让你求一个串的后缀子串与另一个串的最长公共前缀LCP的长度(用ex数组存下) 具体理解可以参照刘雅琼前辈的扩展KMP的PPT https://wenku.baidu.com/view/64ac5384b9d528ea81c779ed.html 上代码 # pragma GCC optimize("O2") # include <bits/stdc++.h> # define ll long long using namespace std ; const int maxn = 2e6 + 7 ; char str [ maxn ] , tr [ maxn ] ; int l , li , nxt [ maxn ] , ex [ maxn ] ; //nxt实际上就是自己对自己的ex数组,ex就代表每一个后缀串对模板串的最长公共前缀(LCP)的长度 void ekmpgetnxt ( ) { int a = 0 , p = 0 ; //p代表最长匹配的长度,a代表开始匹配的位置 nxt [ 0 ] = l ; for ( int i = 1 ; i < l ; i ++ ) { if ( i >= p || i + nxt [ i

字符串匹配算法之————KMP算法

北城余情 提交于 2019-11-28 15:41:35
上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符。但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博客: https://blog.csdn.net/weixin_36604953/article/details/78576637 该博客详细的描述了KMP算法原理。下面的代码实现了KMP算法: 1 //使用暴力穷举法, KMP算法完成字符串匹配算法 2 # include "iostream" 3 #include"string" 4 #include"vector" 5 using namespace std; 6 vector<int>& BFmatch(string & , string & , vector<int>&); 7 vector<int>& KMPStrMatch(string &, string &, vector<int>&); 8 void ShowPos(vector<int>& ); 9 int main() 10 { 11 string ModelStr, SonStr; 12 vector<int> pos; 13 cout << "请输入待匹配字符串:"; 14 cin >> ModelStr ; 15 cout << endl; 16 cout

【转载】从头到尾彻底理解KMP算法

早过忘川 提交于 2019-11-28 15:35:52
1、引言 ①字符串匹配,暴力时间复杂度O(N*M),一旦发生匹配失败,S串和T串都要回退到起点,重新开始一轮匹配。 int ViolentMatch(char* s, char* t) { int sLen = strlen(s); int tLen = strlen(t); for(int i=0;i<sLen;i++){ //S串 int j=0; for(;j<tLen;j++){ //T串 if(s[i+j]!=t[j]) break; //匹配失败 } if(j==tLen) return i; //匹配完全 } return -1; } 暴露问题:一旦发生失败,S串和T串都需要回退到起始匹配点。有什么方法可以只让T串回退,S串不回退?KMP应用而生。 ②KMP时间复杂度O(N+M) 思路:每次匹配失败,能不能不回退,S串不回退,T串回退到最大前缀,引入next数组。 参考: https://blog.csdn.net/wardseptember/article/details/78801491 来源: https://www.cnblogs.com/IIYMGF/p/11400053.html