POJ 3461 Oulipo(自己YY的模式匹配算法)
2014-05-05 02:54
288 查看
请不要随便指点别人该怎么做、每个人的人生都应该自己掌握、你给不了别人一切、你也不懂别人的忧伤、
微笑不代表快乐、哭泣不一定悲伤
不努力怎么让关心你的人幸福、不努力怎么让看不起你的人绝望、
我用生命在奋斗——lx_Zz
—————————————————————————————————————————————————————————————
————————————————————————— 华丽的分割线 ————————————————————————————
—————————————————————————————————————————————————————————————
看各种大牛的文章看了两个小时、关于模式匹配有很多种算法、KMP、BM、还有吊炸天编译原理的DFA的正则文法匹配、简直只能ORZ。。。
决心不看模板、根据思想自己YY、果然还是让我YY出来了。。。别告诉我是POJ数据太弱。。。那我想死的心都有了→_→
好吧、一会儿再切几道题看看是不是水过去的、
其实思想很简单、由于直接BF算法是肯定会TLE、最开始我写了一遍、TLE了之后、开始YY模式匹配、为了消除回溯、我们可以根据已有的信息来判断从前面某一个开始重新匹配、不一定要从头开始、其实这些都是扯淡的。。。
我说我自己的思考过程好了、我先自己随便举一个例子要匹配的串是“abacabx”、文本串是“abacabwab”
前面都是一样的直接跳过、当x和w不一样的时候、我们是不是一定要重新从下一个字符开始找呢?
仔细模拟一下、你会发现其实就是跳到了第二个ab那里、我们从ab后面那个字符拿来比较就行了、对不对?
这样是不是节约了很多时间、
那就转化成了求对于每个当前字符、它的前缀和后缀最长相等是多少、
比如:abcab 当前最长的前缀和后缀相等ab是2
嗯、那么知道了这个、怎么在线性时间内求解这个辅助数组的值呢?
我自己YY的是分三种情况考虑、
1、首先判断是否可以接在前一个的后面
2、如果不能、则看是否和首字符相等、相等为1
3、不等为0
然后求出这个辅助之后就是遍历的时候如果不等就根据辅助的值来变化模式串的匹配位置
表述不是很清楚、不过代码写的很详细、
微笑不代表快乐、哭泣不一定悲伤
不努力怎么让关心你的人幸福、不努力怎么让看不起你的人绝望、
我用生命在奋斗——lx_Zz
—————————————————————————————————————————————————————————————
————————————————————————— 华丽的分割线 ————————————————————————————
—————————————————————————————————————————————————————————————
12839191 | lx_Zz | 3461 | Accepted | 1380K | 63MS | G++ | 1972B | 2014-05-05 02:25:14 |
决心不看模板、根据思想自己YY、果然还是让我YY出来了。。。别告诉我是POJ数据太弱。。。那我想死的心都有了→_→
好吧、一会儿再切几道题看看是不是水过去的、
其实思想很简单、由于直接BF算法是肯定会TLE、最开始我写了一遍、TLE了之后、开始YY模式匹配、为了消除回溯、我们可以根据已有的信息来判断从前面某一个开始重新匹配、不一定要从头开始、其实这些都是扯淡的。。。
我说我自己的思考过程好了、我先自己随便举一个例子要匹配的串是“abacabx”、文本串是“abacabwab”
前面都是一样的直接跳过、当x和w不一样的时候、我们是不是一定要重新从下一个字符开始找呢?
仔细模拟一下、你会发现其实就是跳到了第二个ab那里、我们从ab后面那个字符拿来比较就行了、对不对?
这样是不是节约了很多时间、
那就转化成了求对于每个当前字符、它的前缀和后缀最长相等是多少、
比如:abcab 当前最长的前缀和后缀相等ab是2
嗯、那么知道了这个、怎么在线性时间内求解这个辅助数组的值呢?
我自己YY的是分三种情况考虑、
1、首先判断是否可以接在前一个的后面
2、如果不能、则看是否和首字符相等、相等为1
3、不等为0
然后求出这个辅助之后就是遍历的时候如果不等就根据辅助的值来变化模式串的匹配位置
表述不是很清楚、不过代码写的很详细、
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; char str1[10005]; char str2[1000005]; int next[10005]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%s%s",str1,str2); int len1=strlen(str1); next[0]=-1; for(int i=1;i<len1;i++) { if(str1[i]==str1[next[i-1]]) { next[i]=next[i-1]+1; } else if(str1[i]==str1[0]) { next[i]=1; } else next[i]=0; } int len2=strlen(str2); int ans=0; int flag=0; for(int i=0,j=0;i<len2;) { int ff=0; if(str1[j]==str2[i]) { i++;j++; if(j>=len1) { ans++; j=next[j-1]; } } else { while(str1[j]!=str2[i]) { if(j==0) { ff=1; break; } j=next[j-1]; if(j==-1) { ff=1; break; } } if(ff) { if(str1[0]==str2[i]) { i++;j=1; } else { i++;j=0; } } } } printf("%d\n",ans); } return 0; }
相关文章推荐
- poj 3461 KMP模式匹配算法
- (串的模式匹配4.6.2)POJ 3461 Oulipo(KMP算法的应用——求一个单词在一行文本中的出现次数)
- 字符串模式匹配:POJ 3461 Oulipo
- POJ 3461 Oulipo hash求匹配
- (串的模式匹配4.6.1)POJ 3080 Blue Jeans(使用朴素的模式匹配算法求最长的公共子串)
- poj_3461 Oulipo(KMP:找出所有模式串)
- POJ 3461 Oulipo(KMP匹配)
- POJ-3461 Oulipo-匹配的字符有几个(KMP算法)
- poj 3461 Oulipo (求匹配字符串的个数)(KMP)
- poj 3461 KMP(模式匹配模板)
- 教材上关于模式匹配中的求next数组的算法不易理解,本人自己编写了一个具有相同功能的子函数
- POJ 3461 Oulipo 【KMP多次匹配,新手入门】
- POJ 3461(模式匹配数&覆盖函数)
- [KMP求模式在主串出现次数]POJ 3461 Oulipo
- POJ 3461 Oulipo (求模式串在文本串中出现的次数)
- Oulipo poj 3461 KMP连续匹配(有重合)
- 模式匹配KMP POJ 3461
- POJ 3461 Oulipo(模式串在主串中出现的次数)
- POJ 3461 Oulipo(KMP求匹配次数)
- POJ 1469 COURSES(匈牙利算法二分图最大匹配)