博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
kmp 字符串匹配
阅读量:5113 次
发布时间:2019-06-13

本文共 2037 字,大约阅读时间需要 6 分钟。

kmp的详解在百度上有许多博客群雄辩舌,各有千秋。看着那些证明和解释实在吓人,太长了,今天回顾kmp发现自己已经忘的差不多了,去看百度也不愿意看,就给自己做个笔记,方便以后好回忆,再也不用被那些长篇大论吓到了。

回忆第一步:算法用途

在字符串1中找是否存在字符串2,eg:abxabwabxad中是否有abxad。

回忆第二步:为什么要用算法

暴力不行吗?呃呃呃,Time Limited。

回忆第三步:节省时间的想法是什么

每次暴力都产生了很多有用信息,比如第一次匹配到字符串2的最后一位发现不同后,我们不必从字符串1的b开始找,可以从第二个a开始找。 

回忆第四步:怎么实现想法

有一个next数组。

回忆第五步:这数组干嘛用的

next[i]表示字符串1中起点为0,终点为i的子串的最大前缀与后缀相同位数。

回忆第六步:巴拉巴拉的缀是啥东东

字符串eg:ababc,前缀是:a,ab,aba,abab  后缀是:c,bc,abc,babc

ababa的最大前缀与后缀相同位数是3,aba

回忆第七步:这数组怎么求,呃,要不暴力

不用暴力,用一个标记k,遍历一遍字符串就可以了。

回忆第八步:遍历一遍是怎么做到的,死狗欸

好吧,回忆不起来了,那去看别人博客吧。

过了一会儿。。。。

好长啊,还是自己推吧。

k可以初始化为0也可以初始化为-1。我用0吧。k是用来计数,既然用来计数我喜欢从0开始计算。

原理很简单,就是两个指针同时移动,指针i会一直往后走,任性,而k是有变化的。k的计数可以来帮k确定位子。

比较时有两种情况,第一种呢是如果两个指针指的字母相同,这说明前缀和后缀相同的位数可以加一位了,嘿嘿,k++。

另一种情况呢,就是悲剧了,不相同,前缀和后缀不相同了,那k我要去哪呀,可谓何去何从?又回到最初的起点?不对不对,回到最初点是最糟糕的情况,你应该回到你刚刚上一步匹配到的巴拉巴拉缀那里去,即next[k-1],因为说不定回到这里又能和当前i匹配到了呢,不是吗,于是,你就乖乖用了一个while实现了这一步。走到最后你就把next数组求完了,时间复杂度为i的范围O(n),效率杠杠的。

回忆结束,打坐休息。。。。

敲得嘛得,不用实战训练一下吗?代码都还没给出来呢?不用实战我学这算法干嘛?我学这算法有何用?

呃呃呃,就拿一题简单的求next数组的题来过过。

题目链接:http://poj.org/problem?id=2406

题目大意:定义字符串的乘法为a*b=a*b,a^4=aaaa,给出一个长度不超过一百万的字符串,求这字符串为某子串的最大幂。

解题思路:所谓高手过招,只需一眼,因为我不是高手,我用了两眼

第一眼:求next数组,得出某子串的长度为n-next[n-1],n是输入字符串的长度

第二眼:求幂;如果n是子串长度的整数倍,说明可以幂,输出幂,否则该子串不能幂得到原串,即子串就是原串,输出1。

最后献上ac代码(内含next数组求法标码):

1 #include
2 #include
3 #include
4 using namespace std; 5 const int maxn=10000007; 6 int next[maxn]; 7 char str[maxn]; 8 void initnext(int len) 9 {10 int k=0;11 for(int i=1;i
0&&str[k]!=str[i]) k=next[k-1];14 if(str[k]==str[i]) k++;15 next[i]=k;16 }17 return;18 }19 int main()20 {21 while(~scanf("%s",str))22 {23 if(str[0]=='.')24 break;25 memset(next,0,sizeof(next));26 int len=strlen(str);27 initnext(len);28 if(len%(len-next[len-1])==0)29 printf("%d\n",len/(len-next[len-1]));30 else31 printf("1\n");32 }33 return 0;34 }

 

转载于:https://www.cnblogs.com/wwq-19990526/p/10802455.html

你可能感兴趣的文章
DM8168 DVRRDK软件框架研究
查看>>
django迁移数据库错误
查看>>
yii 跳转页面
查看>>
洛谷 1449——后缀表达式(线性数据结构)
查看>>
Data truncation: Out of range value for column 'Quality' at row 1
查看>>
Dirichlet分布深入理解
查看>>
(转)Android之发送短信的两种方式
查看>>
字符串处理
查看>>
HtmlUnitDriver 网页内容动态抓取
查看>>
ad logon hour
查看>>
获得进程可执行文件的路径: GetModuleFileNameEx, GetProcessImageFileName, QueryFullProcessImageName...
查看>>
证件照(1寸2寸)拍摄处理知识汇总
查看>>
罗马数字与阿拉伯数字转换
查看>>
Eclipse 反编译之 JadClipse
查看>>
Python入门-函数
查看>>
[HDU5727]Necklace(二分图最大匹配,枚举)
查看>>
距离公式汇总以及Python实现
查看>>
设计模式之装饰者模式
查看>>
一道不知道哪里来的容斥题
查看>>
Blender Python UV 学习
查看>>