kmp

【模板】KMP字符串匹配【KMP】

匿名 (未验证) 提交于 2019-12-03 00:43:02
给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。 思路: K M P 算法模板题。 K M P 这个算法一开始真的很难懂,但是接触后过一会再研究就会豁然开朗。这个东西也很难解释原理,只有自己搞懂。 推荐的 K M P 讲解: https://blog.csdn.net/starstar1992/article/details/54913261/ 时间复杂度 O ( n ) ,暴力时间复杂度 O ( n × m ) #include <cstdio> #include <iostream> #include <cstring> using namespace std; int next[ 1000101 ],n,m,j; char a[ 1000101 ],b[ 1000101 ]; int main() { cin >>a+ 1 ; cin >>b+ 1 ; n =strlen(a+ 1 ); m =strlen(b+ 1 ); next[ 1 ]= 0 ; for ( int i= 1 ;i<m;i++) // 求next数组 { while (b[i+ 1 ]!=b[j+ 1 ]&&j> 0 ) j=next[j]; // 不匹配 if (b[i+ 1 ]==b[j+ 1 ]) j++; // 匹配成功 next[i+ 1 ]= j; } j =

【KMP &amp;&amp; 所有前缀,在原串出现次数(可重叠)和】HDU - 3336 Count the string

匿名 (未验证) 提交于 2019-12-03 00:30:01
Step1 Problem: 给你字符串s, 求所有前缀,在原串出现次数(可重叠)和。 Step2 Ideas: 个人习惯从0开始,next[0] = 0; next[i] : 代表下标从 0 到 i 这个子串,后缀 = 前缀 最长长度(不包括自身)。 枚举 i 从 0 到 len-1,对于每个 i 结尾的 所有后缀 = 前缀 的个数都求出来,然后求和。 Step3 Code: #include<bits/stdc++.h> using namespace std ; const int N = 2e5 + 100 ; char s[N]; int nex[N]; void get_next() { int len = strlen (s); nex[ 0 ] = 0 ; for ( int i = 1 ; i < len; i++) { int j = nex[i- 1 ]; while (j && s[i] != s[j]) j = nex[j- 1 ]; if (s[i] == s[j]) nex[i] = j+ 1 ; else nex[i] = 0 ; } } int main() { int T, n; scanf ( "%d" , &T); while (T--) { scanf ( "%d %s" , &n, s); get_next(); int ans = n;

【改造KMP】洛谷P2375 动物园

匿名 (未验证) 提交于 2019-12-03 00:26:01
范围很狗,不要轻信! https://www.luogu.org/problemnew/show/P2375 我们大家都知道 K M P K M P 的 n e x t n e x t 数组吧 (不知道也无所谓) 其定义是: 在字符串 s s 从第1位开始长度为 i i 的子串中,既是前缀又是后缀的最长的子串的长度( 可以重叠 )称为 n e x t [ i ] n e x t [ i ] 先定义这样一个数组 n u m n u m : 在字符串 s s 从第1位开始长度为 i i 的子串中,既是前缀又是后缀的最长的子串的长度( 不可重叠 )称为 n e x t [ i ] n e x t [ i ] 求 ∏ n 1 i = 0 ( n u m [ i ] + 1 ) ∏ i = 0 n 1 ( n u m [ i ] + 1 ) ˼· 唉呀妈呀,好麻烦啊,我们 充分 理解之后就会发现 所有 n u m [ i ] n u m [ i ] 的两倍均小于 i i ,所以我们就可以加个特判就行了 #include<cstdio> #include<cstring> #define mod 1000000007 using namespace std ; int kmp[ 1000001 ],num[ 1000001 ],t,n; long long ans; char a[

B - Oulipo(KMP)

匿名 (未验证) 提交于 2019-12-03 00:19:01
B - Oulipo Time Limit: 1000 Memory Limit: 65536 64bit IO Format: %I64d & %I64u Submit Status Practice POJ 3461 use MathJax to parse formulas Description '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

KMP算法详解 (转载)

匿名 (未验证) 提交于 2019-12-03 00:18:01
最近在刷题的时候遇到了KMP 算法的一些题目,回想起来自己关于数据结构和算法的知识内容都已经忘了。于是打算重新复习一遍。就从KMP算法开始吧。因为自己水平还不够,也讲不清楚。于是就从网上转载了两篇博文。 https://blog.csdn.net/v_JULY_v/article/details/6545192 http://blog.csdn.net/v_JULY_v 。 作者:滨湖,July、yansha。 说明:初稿由滨湖提供,July负责KMP部分的勘误,yansha负责BM部分的修改。全文由July统稿修订完成。 出处: http://blog.csdn.net/v_JULY_v 。 引言 六、教你从头到尾彻底理解KMP算法、updated 之后,KMP算法会写一个续集;2、写这个kMP算法的文章很多很多,但真正能把它写明白的少之又少;3、这个KMP算法曾经困扰过我很长一段时间。我也必须让读者真真正正彻彻底底的理解它。希望,我能做到。 模式匹配, . , . , , HTTP , , HTTP . KMP BM BM BM KMP BM 第一部分、KMP算法 1、回溯法字符串匹配算法 [cpp] view plain copy //代码1-1 //查找出模式串patn在主串src中第一次出现的位置 //plen为模式串的长度 //返回patn在src中出现的位置

AcWing 831. KMP字符串

匿名 (未验证) 提交于 2019-12-03 00:17:01
https://www.acwing.com/problem/content/833/ #include <iostream> using namespace std; const int N = 10010, M = 100010; int n, m; int ne[N]; char s[M], p[N]; int main() { cin >> n >> p + 1 >> m >> s + 1; //求next过程 //i从2开始,因为next[1]=0,如果第一个字母失败了,只能从0开始 for (int i = 2, j = 0; i <= n; i ++ ) { while (j && p[i] != p[j + 1]) j = ne[j]; if (p[i] == p[j + 1]) j ++ ; ne[i] = j; } //kmp匹配过程 for (int i = 1, j = 0; i <= m; i ++ ) { while (j && s[i] != p[j + 1]) //当j没有退回起点,并且当前的s[i]不能和下一个j的位置匹配 j = ne[j];//移动,保证之前的相等 直到匹配位置,或者j已经到开头了 if (s[i] == p[j + 1]) //如果已经匹配了 j ++ ; //j往下移动 if (j == n) {//说明匹配成果

KMP字符串匹配 模板 洛谷 P3375

匿名 (未验证) 提交于 2019-12-03 00:15:02
如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。 为了减少骗分的情况,接下来还要输出子串的前缀数组next。 (如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。) 样例: 输入 ABABABC ABA 输出 1 3 0 0 1 当然是使用KMP啦,只不过这个要求比较高一些。 注意这里要输出的next数组内容是不能进行优化的那种,否者就会WA,带有优化的可以看第一个代码。 详情见代码。这个也可以算作一个模板了。 //这个是对next进行的优化 void getnext() //做的第一步是获得next【】的值 { int i=0,k=-1; next[0]=-1; while(i<lenb) { if(k==-1)//这里和平常的有些不同,这里进行了一些优化,将两个条件分开了。 { next[++i]=++k; continue; } if (b[i]==b[k]) { if(b[i+1]==b[k+1]) //这里进行了优化,一般介绍KMP的文章中都有会这个。 next[++i]=next[++k]; else next[++i]=++k; } else k=next[k]; } } #include<cstdio> #include<cstring> using namespace std; const int

KMP算法计算next值和nextVal值

匿名 (未验证) 提交于 2019-12-03 00:14:01
KMP算法: 给定一个主串S及一个模式串P,判断模式串是否为主串的子串;若是,返回匹配的第一个元素的位置(序号从1开始),否则返回0; 这里先不写算法,仅仅计算next和nextVal值 那么计算时只用到子串,也就是模式串 这里模式串为: abaabcac 第一步将模式串写上序号,我们这里从1开始(有的从0开始,建议充1开始) 然后计算出maxL值,列出从第一个开始的子串,找出相等的前缀和后缀的个数 如果2>看不懂的话,看3>, 2>计算maxL值 所以maxL值 如果这个看不懂的话, 看下面的3> 3>, 如果2>看懂了这个就不用看了 依次类推 4>计算next值 接下来将maxL复制一行,去掉最后一个数,在开头添加一个-1,向右平移一个格,然后每个值在加1的到next值 5>计算nextVal值,首先将第一个为0,然后看next和maxL是否相等(先计算不相等的) 当next和maxL不相等时,将next的值填入 当next和maxL相等时,填入对应序号为next值得nextVal值 所以整个nextVal值为: 来源:博客园 作者: Lucky& 链接:https://www.cnblogs.com/xiaokang01/p/11593513.html

HDU 1686 Oulipo (KMP)

。_饼干妹妹 提交于 2019-12-03 00:05:38
题目链接: HDU 1686 Problem Description 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

KMP

匿名 (未验证) 提交于 2019-12-02 23:59:01
KMP: 字符串的特征向量:由特征数组成的一维数组 字符串的特征数:在i位置上的首尾真子串能够匹配的最大长度。 e.g.字符串a b a c a b 对应的特征向量是001012 KMP的主要思想是在已经匹配的模式串子串中,找到最大的相同的前缀和后缀,移动是他们重叠。 e.g. 找到P=['a b a c a b']在S=['a b a c a a b a c a b a c a b a a b b']中的位置 def gen_pnext ( p ): """ 获取字符串s的特征向量 """ index , L = 0 , len ( p ) pnext = [ 0 ] * L for i in range ( 1 , L ): k = pnext [ i - 1 ] while k | 0 and p [ i ] != p [ k ]: k = pnext [ k - 1 ] if p [ i ] == p [ k ]: pnext [ i ] = k + 1 else : pnext [ i ] = 0 return pnext def KMP_algorithm ( s , p ): ''' KMP字符串匹配的主函数 若存在字串返回字串在字符串中开始的位置下标,或者返回-1 ''' pnext = gen_pnext ( p ) print ( pnext ) n = len