kmp

FZU - 1901 Period II (kmp)

我们两清 提交于 2020-03-28 02:27:38
传送门: FZU - 1901 题意:给你个字符串,让你求有多少个p可以使S[i]==S[i+P] (0<=i<len-p-1)。 题解:这个题是真的坑,一开始怎么都觉得自己不可能错,然后看了别人的博客打脸了,发现自己掉坑了了...一开始想的是找出最小循环节,只要每次输出多加一个循环节,最后输出len就好了。后来发现最小循环节的倍数并不能表示所有循环节。看到的一组例子ababaaaabab,应该输出7,9,11;但是最小循环节的输出是7,11。 1 #include<iostream> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 using namespace std; 6 7 char a[1000100]; 8 int nt[1000100]; 9 10 void kmp_nt(int m) 11 { 12 int i,j; 13 i = 0; 14 nt[0] = j =-1; 15 while(i < m){ 16 while(j!=-1&&a[i]!=a[j]) 17 j = nt[j]; 18 if(a[i]==a[j]||j==-1){ 19 i++; 20 j++; 21 nt[i]=j; 22 } 23 } 24 } 25 26 int main() 27 { 28 int t;

Xtreme9.0 - Pattern 3 KMP

霸气de小男生 提交于 2020-03-25 06:01:13
Pattern 3 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/car-spark Description Vangelis the bear received a digital signal pattern generator that his brother Mitsos built. The generator produces a signal that is encoded using the Latin alphabet. Vangelis starts the generator for some time and records the signal generated. He wants to study the sample he received and try to identify the smallest pattern that the generator could be using to generate the sample. Your task is to help Vangelis by writing a program that will calculate the length of the smallest valid

KMP的理解与模板

我的未来我决定 提交于 2020-03-18 11:57:27
                  KMP T 串主串 P 串模式串 i T 串: A B C A B C D H I J K P 串: A B C E j 保持 i 指针不回溯,通过修改 j 指针,让模式串尽量地移动到有效的位置 接下来我们自己来发现 j 的移动规律: 如图: C 和 D 不匹配了,我们要把 j 移动到哪?显然是第 1 位。为什么?因为前面有一个 A 相同啊: 如下图也是一样的情况: 可以把 j 指针移动到第 2 位,因为前面有两个字母是一样的: 当匹配失败时, j 要移动到下一个位置 k 。(模式串)存在着这样的性质: 最前面的 k 个字符和 j 之前的最后 k 个字符是一样的。 P[0~k-1] ==P[j-k~j-1] 比如 : a b c d a b c i == : 0 1 2 3 4 5 6 7 next:-1 0 0 0 0 1 2 3 初始化Next[]数组: void get_next() //初始化next数组 lenp为p数组的长度 { int i,j; Next[0] = j = -1; i = 0; while(i<lenp) //最后一位的判断其实是多余的 { while(j!=-1&&p[j]!=p[i]) j = Next[j]; Next[++i] = ++j; } } ------------------------------

字符串匹配算法-KMP

耗尽温柔 提交于 2020-03-09 04:50:15
文章目录 字符串匹配问题 KMP算法 简介 前缀/后缀/部分匹配表 甲的疑问1:k = next[k-1]是什么鬼? 结论 得到部分匹配表后匹配过程 算法特点 字符串匹配问题 引用知乎用户 灵茶山艾府 的举例,假设我们有两个角色,甲和乙 甲 : abbaabbaaba 乙 : abbaaba 一天清晨,乙对甲说,你心里到底有没有我,告诉一下我在你心中的位置。甲心中一紧,从头开始一一与乙的字符进行比较。 但是,前面的六位都能匹配,当比较到第七位时,不匹配。甲试着像往常一样暴力匹配,回退到自己的第二个字符,从乙的开头开始继续比较。这一位匹配,则继续匹配下一位,不匹配再回退到上一次开始匹配的下一个字符重头开始匹配。如下图所示: 这样没过一会儿,甲就对乙说,我找到了,放心吧,我心里一直有你呢,然后骄傲地告诉了乙在自己心中的具体位置。乙表示还不错,一是觉得心里面有它,二是甲的查询速度这么快,说明甲没有其他相好的再心里(甲心里存放的字符数目较少). 但终有一天,甲心中想的相好的越来越多,而且这些相好的很大一部分还和乙很像,这样,甲的字符串就变得越来越长。 又是一个清晨,乙又对甲说,你心里到底还有没有我。甲JH一紧,捏了一把冷汗,心想自己心里现在不是那么干净,相好的那么多,要是还像以前那么暴力搜索,不知道要找到什么时候。果然,乙又开口了,快告诉我在你心中的位置。不过,乙又说,今天天气好

字符串子串匹配KMP算法

别来无恙 提交于 2020-03-07 20:04:38
子串匹配问题:返回一个子串在字符串中第一次出现的下标,若无则返回-1 KMP: 一个朴素的子串匹配如下:(以下使用TypeScript语言编写) private subStringIndex(source:string,target:string):number{ if(target.length>source.length||!source||!target){ return -1; } let res=-1; for(let i=0;i<=source.length-target.length;i++){ if(source[i]==target[0]){ let temp=true; for(let j=0;j<target.length;j++){ //可以看到使用了两层的for循环,时间复杂度是0(n^2) if(source[i+j]!=target[j]){ temp=false; break; } } if(temp){ res=i; return res } } } return res; } 在子串与母串不匹配时,母串的i会回退到子串第一个的位置,减少这个回退的数量就是KMP的目标 KMP:通过getNext获得当source[i+j]!=target[j]时i向前移动多少位置 next=当匹配到这个字符不一致时

牛客oj 习题4.7String Matching(KMP)&&习题4.6字符串匹配

心已入冬 提交于 2020-03-07 04:50:11
练KMP我认为没什么技巧,背代码就完事了。我的口诀:(仅限于自己理解) (1)、先回溯主串后回溯子串,回溯哪个哪个为负一; (2)、推nextTable时拿子串对应的下标开刀。 PS:这题把nextTable数组换成next数组居然有歧义,这辣鸡编译器居然还会把next数组设成关键字,第一次碰到这种错害得我检查了一个小时,真是绝了。 #include <cstdio> #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <climits> using namespace std; const int MAXN = 1000005; const int INF = INT_MAX; int nextTable[MAXN]; void getNext(string &text, string &pattern){ int n = text.size(); int m = pattern.size(); int i, j; j = 0; nextTable[j] = -1; i = nextTable[j]; while(j < m){ if(i == -1 || pattern[i] == pattern[j]){ i++; j+

两种KMP题+KMP模版整理

那年仲夏 提交于 2020-03-04 04:35:27
最近稍微看了下KMP,不是很懂他们大神的A题姿势,但是模版总该还是要去学的。 其中next数组的求法有两处区别。 第一种:求主串中模式串的个数。HDU2087 剪花布条和HDU4847 Wow! Such Doge!。这两道都比较水可以暴力string::find函数过, 第一个代码: #include<iostream> #include<algorithm> #include<cstdlib> #include<sstream> #include<cstring> #include<cstdio> #include<string> #include<deque> #include<cmath> #include<queue> #include<set> #include<map> using namespace std; typedef long long LL; int nextval[101010]; void getnext(char s[],int next[]) { int j=0,k=next[0]=-1; int len=strlen(s); while (j<len-1)  // { if(k==-1||s[k]==s[j]) { j++; k++; next[j]=next[k];  // } else k=next[k]; } } int sea(char

字符串算法

允我心安 提交于 2020-03-02 00:25:24
KMP 模板: int kmp [ MAXN ] ; //kmp[i]的基本定义是:在第1-第i位中真前缀与真后缀相同的部分最长是多长 char a [ MAXN ] , b [ MAXN ] ; //a是文本串,b是模板串,kmp数组是b的next数组 (注意:数组从1开始) int kmpp ( ) { int la , lb , j = 0 ; //j可以看做表示当前已经匹配完的模式串的最后一位的位置 la = strlen ( a + 1 ) ; lb = strlen ( b + 1 ) ; for ( int i = 2 ; i <= lb ; i ++ ) { //自己匹配自己 while ( j && b [ i ] != b [ j + 1 ] ) j = kmp [ j ] ; //找到最长的前后缀重叠长度 if ( b [ j + 1 ] == b [ i ] ) j ++ ; kmp [ i ] = j ; } j = 0 ; int res = 0 ; for ( int i = 1 ; i <= la ; i ++ ) { while ( j > 0 && b [ j + 1 ] != a [ i ] ) j = kmp [ j ] ; //如果不匹配,则将利用kmp数组往回跳 if ( b [ j + 1 ] == a [ i ] ) j ++ ;

poj 3461 Oulipo(KMP模板题)

你离开我真会死。 提交于 2020-02-29 07:34:42
Oulipo Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 36903 Accepted: 14898 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

KMP模式匹配算法

↘锁芯ラ 提交于 2020-02-27 20:07:01
title: KMP模式匹配算法 date: 2020-02-26 17:24:29 tags: datastructure 这几天复习到数据结构的串的模式匹配,看到KMP算法那么寥寥几行的代码,原本觉得这部分内容很简单,直到我开始尝试去理解它,我才发现我跟大佬的差别。 KMP算法的基本思路 KMP算法,是名分别为K、M、P的三个美国大佬发明的,算是对传统的朴素模式匹配算法的改进。我们先规定,讨论模式串下标均从1开始。朴素模式匹配算法就不谈了,这个有脑子就能想出来,但朴素模式匹配算法存在一个弊端——当模式串有较多重复元素存在时,主串指针i其实做了很多没有必要的回溯。 而如果想跳过这些没有必要比较的情况,那么就可以想到,主串指针是没有必要回退的,因为当发生与模式串失配的情况时,可以确定的是,此前成功匹配的若干元素形成的字串,其实就是模式串的一个真字串,那么对于这样的一个字串,它的头部和尾部如果发生了重复,就只需要往回移动模式串指针就好了,但是又不需要往回移到初始位置,因为我们看到他的头部和尾部发生了重复,又由于这个头部重复的部分与现在主串指针前的那个模式串真字串重复,而这部分就是真字串的尾部,所以最有利的做法应该是将模式串指针移动至头部重复字串的后一位,再来与当前的主串指针比较。这样,就避免了主串的回溯,单就这个算法本身,简单来看时间复杂度应该是o(n)。 以下是KMP主代码