hdu2087-自己的理解&kmp讲解-剪花布条
2017-08-20 10:43
183 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2087
链接
时隔多年,终于理解kmp了。。
1 进行字符串匹配,如果进行暴力匹配的话,(即一个一个找,时间复杂度O(len1*len2),是不可取的,)
2 所以需要改进这个算法。 如何改进,这个问题,引起了三个年轻小伙子的注意,有一天他们在一个小溪边玩,突然发现了一个老太太在磨针,并且针的 头和尾各有一部分相同的花纹,就好像金箍棒的两头一样。然后,三个人之间的小k突发奇想,在纸上画了这么一个图。
他发现,大人们在进行暴力匹配的时候,当出现了蓝色的情况(红色是目标串,下面是模式串,如果前面的绿色相同,那么模式串就可以跳过去,跳过前面的比较。)
小m看了看,朗声道,想法不错,咋写啊。那个绿色的怎么表示??
小p说,好办,你有没有发现,这就是以i为最后一个字符 的 模式串的子串 的 最长的 相同前缀和后缀()??上面那个是后缀,虾米那那个是 前缀,(后缀顶到后,前缀要顶到前,实在不会,就先去学习 后缀数组qwq)
小m又说,如果转移又匹配失败了呢。。还要从头开始?
这时,小p说,一看你c语言课就没好好听,这不是老师常说的递归的思想么,如果匹配失败,就让 这个 最长的 相同前缀和后缀 当成一个 子串,继续递归寻找他的 ,判断 他的相同前缀和后缀 后面的那个元素是否和 蓝色字母相同。如果相同就可以,如果不同在递归。直到没有,就从头再来。
说时迟,那时快,小k马上画了一个图。重人恍然大悟,笑嘻嘻的回家了。
next[i]保存的 1————i-1 这个串的最长 相同 前缀和后缀,
遍历的过程,如果每次找到都取0,就是统计个数。(相当于找到一个后,母串子串都在当前左对齐,重新找。。qwq)
算法思想: 字符串的前后缀,问题转化为更小的问题(dp??递归?,反正就是酱紫)
附赠一个 代码 和kuangbin神的 模板。
链接
时隔多年,终于理解kmp了。。
1 进行字符串匹配,如果进行暴力匹配的话,(即一个一个找,时间复杂度O(len1*len2),是不可取的,)
2 所以需要改进这个算法。 如何改进,这个问题,引起了三个年轻小伙子的注意,有一天他们在一个小溪边玩,突然发现了一个老太太在磨针,并且针的 头和尾各有一部分相同的花纹,就好像金箍棒的两头一样。然后,三个人之间的小k突发奇想,在纸上画了这么一个图。
他发现,大人们在进行暴力匹配的时候,当出现了蓝色的情况(红色是目标串,下面是模式串,如果前面的绿色相同,那么模式串就可以跳过去,跳过前面的比较。)
小m看了看,朗声道,想法不错,咋写啊。那个绿色的怎么表示??
小p说,好办,你有没有发现,这就是以i为最后一个字符 的 模式串的子串 的 最长的 相同前缀和后缀()??上面那个是后缀,虾米那那个是 前缀,(后缀顶到后,前缀要顶到前,实在不会,就先去学习 后缀数组qwq)
小m又说,如果转移又匹配失败了呢。。还要从头开始?
这时,小p说,一看你c语言课就没好好听,这不是老师常说的递归的思想么,如果匹配失败,就让 这个 最长的 相同前缀和后缀 当成一个 子串,继续递归寻找他的 ,判断 他的相同前缀和后缀 后面的那个元素是否和 蓝色字母相同。如果相同就可以,如果不同在递归。直到没有,就从头再来。
说时迟,那时快,小k马上画了一个图。重人恍然大悟,笑嘻嘻的回家了。
next[i]保存的 1————i-1 这个串的最长 相同 前缀和后缀,
遍历的过程,如果每次找到都取0,就是统计个数。(相当于找到一个后,母串子串都在当前左对齐,重新找。。qwq)
算法思想: 字符串的前后缀,问题转化为更小的问题(dp??递归?,反正就是酱紫)
附赠一个 代码 和kuangbin神的 模板。
#include <iostream> #include <bits/stdc++.h> using namespace std; /* 1 关于next数组的计算。 kmp之所以能够简化速度,是因为记录了模式串的最长公共前缀和后缀 */ int nex[105];//计算 next数组, // 并且 nex[i] 是 i-1串的 最长的(前缀和后缀相同的)长度 int ans; void next(char s[]){ //memset(nex,-1,sizeof(nex)); int len=strlen(s); //cout<<"len "<<len<<endl; int i=0;//下面就要计算 next数组了 int k=-1;//记录最大next nex[0]=-1; while(i<len){ if(k==-1||s[i]==s[k]){ i++;k++; nex[i]=k;//记住,nex i是i-1串的 最长前后缀。 } else k=nex[k];//递归,在最长 前后缀中间继续寻找。 } } void kmp(char a[],char b[]){ next(b); int len1=0; int len2=0; int siz1=strlen(a); int siz2=strlen(b); while(len1<siz1){ while(len2>0&&a[len1]!=b[len2]){ len2=nex[len2]; }// 第一次位置, if(a[len1]==b[len2]) {len2++;} if(len2==siz2){ ans++; //len2=nex[len2];// 寻找出现的次数。 len2=0;// 让模式串从头开始找。 } len1++; } } int main() { char a[1003],b[1003]; while(~scanf("%s",a)){ ans=0; if(strcmp(a,"#")==0){ break; } scanf("%s",b); kmp(a,b); printf("%d\n",ans); } return 0; }
kuangbin 模板 #include <iostream> #include <cstring> using namespace std; const int N = 1000002; int next ; char S , T ; int slen, tlen; void getNext() { int j, k; j = 0; k = -1; next[0] = -1; while(j < tlen) if(k == -1 || T[j] == T[k]) next[++j] = ++k; else k = next[k]; for(int i=0;i<tlen;i++) cout<<next[i]<<" "<<endl; } /* 返回模式串T在主串S中首次出现的位置 返回的位置是从0开始的。 */ int KMP_Index() { int i = 0, j = 0; getNext(); while(i < slen && j < tlen) { if(j == -1 || S[i] == T[j]) { i++; j++; 4000 } else j = next[j]; } if(j == tlen) return i - tlen; else return -1; } /* 返回模式串在主串S中出现的次数 */ int KMP_Count() { int ans = 0; int i, j = 0; if(slen == 1 && tlen == 1) { if(S[0] == T[0]) return 1; else return 0; } getNext(); for(i = 0; i < slen; i++) { while(j > 0 && S[i] != T[j]) j = next[j]; if(S[i] == T[j]) j++; if(j == tlen) { ans++; j = next[j]; } } return ans; } int main() { int TT; int i, cc; cin>>TT; while(TT--) { cin>>S>>T; slen = strlen(S); tlen = strlen(T); cout<<"模式串T在主串S中首次出现的位置是: "<<KMP_Index()<<endl; cout<<"模式串T在主串S中出现的次数为: "<<KMP_Count()<<endl; } return 0; }
相关文章推荐
- HDU1686[Oulipo]&&HDU2087[剪花布条] kmp大水题
- KMP 算法 自己的一些理解
- C语言深度解剖(精讲版)——读书笔记10 &&自己的一些理解
- HDU2087 剪花布条 [KMP]
- KMP算法及应用&(hdu2087剪花布条 )&Power Strings (POJ2046)&Cyclic Nacklace(HDU3746)
- C语言深度解剖(精讲版)——读书笔记3 &&自己的一些理解
- C语言深度解剖(精讲版)——读书笔记21 &&自己的一些理解
- C - 剪花布条 HDU2087( kmp找子串,子串不能有重叠 )
- C语言深度解剖(精讲版)——读书笔记8 &&自己的一些理解
- KMP简单题--Number Sequence&&剪花布条
- UVa 1328 Period (KMP&失配函数的理解)
- 【hdu2087】剪花布条——KMP
- C语言深度解剖(精讲版)——读书笔记5 &&自己的一些理解
- C语言深度解剖(精讲版)——读书笔记15 &&自己的一些理解
- KMP(内含next数组讲解) —— 剪花布条 ( HDU 2087 )
- 【眼见为实】自己动手实践理解数据库REPEATABLE READ && Next-Key Lock
- C语言深度解剖(精讲版)——读书笔记20 &&自己的一些理解
- kmp讲解 & 模板
- KMP 模板+简单讲析 【HDU2087】 剪花布条
- C语言深度解剖(精讲版)——读书笔记1 &&自己的一些理解