kmp算法学习 与 传参试验(常回来看看)
之前在codeforces上做了一道类似KMP的题目,但由于之前没有好好掌握,现在又基本忘记,并没能解答。下面是对KMP算法的一点小总结。
首先KMP算法的核心是纸在匹配过程中,利用模式串的前后缀来加速匹配过程,这一点在自己实验时就可以发现了。其次时KMP算法的核心Next数组,next[j]=k表示对于模式串的【0...j-1】位,最长存在长度为k的相同前后缀,值得注意的是对于kmp而言是不能出现next[j]=j的情况的。而next数组的计算方法我认为本质上还是DP,但是在状态转移过程中又用到了递归的想法,因此使得算法变得复杂。
下面是codeforces上的next数组变种题:http://codeforces.com/contest/1200/problem/E
需要利用next数组的思想,将要合并的两个字符串构建成“S2+S1"的形式,其中的“+”可以防止匹配越界,还应该注意构建时取S1.S2的最小长度从而减小时间复杂度。最后利用next[]的最后一位即可得到合并部分的长度。
这里是自己比较习惯的利用for循环完成next数组构建的写法。
#include <stdio.h> char ch[];
int next[]; char* mmerge(char* ch1,char* ch2,int &len1,int len2)
{
//printf("%d %d ",len1,len2);
int len=len1;if (len2<len) len=len2; for (int i=;i<len;i++)
ch[i]=ch2[i];
ch[len]='+';
for (int i=len*,j=len1-;i>len;i--,j--)
ch[i]=ch1[j];
ch[len*+]=;
// printf("%s\n",ch); next[]=;
for (int i=;i<=len*;i++)
{
int j=next[i-];
while (j && ch[i]!=ch[j])
j=next[j-];
if ( ch[i]==ch[j] ) next[i]=j+;
else next[i]=;
} //printf(" %d ",next[len*2]);
for(int i=next[len*];ch2[i];i++,len1++ )
ch1[len1]=ch2[i];
ch1[len1]=; //printf("%s\n\n",ch1);
return ch1;
} int main()
{
char ch1[];
int n;scanf("%d",&n);
scanf("%s",ch1);
int len1=;
while (ch1[len1]) len1++;
for(int i=;i<n;i++)
{
char ch2[];
scanf("%s",ch2);
int len2=;while (ch2[len2]) len2++;
mmerge(ch1,ch2,len1,len2);
}
printf("%s",ch1);
}
也有正常使用while循环的写法(可能不标准吧)
#include <stdio.h> char ch[];
int next[]; char* mmerge(char* ch1,char* ch2,int &len1,int len2)
{ int len=len1;if (len2<len) len=len2; for (int i=;i<len;i++)
ch[i]=ch2[i];
ch[len]='+';
for (int i=len*,j=len1-;i>len;i--,j--)
ch[i]=ch1[j];
ch[len*+]=; next[]=;
int now=,mlen=;
while (now<=len*)
{
if (ch[now]==ch[mlen])
{
next[now]=mlen+;
now++;mlen++;
}
else
if (mlen==)
next[now++]=;
else
mlen = next[mlen-];
} for(int i=next[len*];ch2[i];i++,len1++ )
ch1[len1]=ch2[i];
ch1[len1]=; return ch1;
} int main()
{
char ch1[];
int n;scanf("%d",&n);
scanf("%s",ch1);
int len1=;
while (ch1[len1]) len1++;
for(int i=;i<n;i++)
{
char ch2[];
scanf("%s",ch2);
int len2=;while (ch2[len2]) len2++;
mmerge(ch1,ch2,len1,len2);
}
printf("%s",ch1);
}
在程序中,也大胆尝试了以前不敢用的传递对象指针以及利用引用&完成传值的操作,希望以后能多用一些这种编程方式,有利于工程实践。另外最开始将ch数组与next数组放置于mmerge函数中,似乎出现了栈溢出的问题(以后需要关注,还不太明白)。
接着做了一道正常KMP例题,http://acm.hdu.edu.cn/showproblem.php?pid=1686,问S1在S2串中出现了多少次?
#include <stdio.h> int ans( char* S, char* P, int* next )
{
int aans=;
int len1=;while (S[len1]) len1++;
int len2=;while (P[len2]) len2++;
next[]=-;
int now=,mlen=-;
while (now<len1)
{
if (mlen==- || S[now]==S[mlen] )
{
mlen++;
now++;
next[now]=mlen;
}
else
mlen=next[mlen];
} int i=,j=;
while (j<len2)
{
if (i==len1) aans++,i=next[i];
if (i==- || S[i]==P[j])
i++,j++;
else
i=next[i]; }
if (i==len1) aans++;
return aans; } int main()
{
int T;scanf("%d",&T);
while (T--)
{
char ch1[];
char ch2[];
scanf("%s%s",ch1,ch2);
int next[];
printf("%d\n", ans(ch1,ch2,next) );
}
}
对于KMP,目前理解了原理,自己也能写出代码,不过感觉还是不够熟练,时常回来看看吧:)
kmp算法学习 与 传参试验(常回来看看)的更多相关文章
- 字符串匹配算法——KMP算法学习
KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...
- KMP算法学习
kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(n ...
- KMP 算法 学习 整理
我自己整理的KMP算法的PDF文件:http://pan.baidu.com/s/1o8yKIi2提取密码:8291 别的就不多说啥了,感谢来自海子 博客园的 资料--
- KMP算法学习(详解)
kmp算法又称“看毛片”算法,是一个效率非常高的字符串匹配算法.不过由于其难以理解,所以在很长的一段时间内一直没有搞懂.虽然网上有很多资料,但是鲜见好的博客能简单明了地将其讲清楚.在此,综合网上比较好 ...
- 字符串匹配的BF算法和KMP算法学习
引言:关于字符串 字符串(string):是由0或多个字符组成的有限序列.一般写作`s = "123456..."`.s这里是主串,其中的一部分就是子串. 其实,对于字符串大小关系 ...
- KMP 算法学习
KMP算法是用来做字符串匹配的.关于字符串匹配,最简单最容易想到的方法是暴利查找,使用双重for循环处理. 该方法的时间复杂度为O((n-m+1)*m) (n为目标串T长度,m为模式串P长度, 从T中 ...
- KMP算法学习以及小结(好马不吃回头草系列)
首先请允许我对KMP算法的三位创始人Knuth,Morris,Pratt致敬,这三位优秀的算法科学家发明的这种匹配模式可以大大避免重复遍历的情况,从而使得字符串的匹配的速度更快,效率更高. 首先引入对 ...
- KMP算法 学习例题 POJ 3461Oulipo
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 37971 Accepted: 15286 Description The ...
- Django学习----js传参给view.py
需求: 散点图中每选择一个点,获取到id之后传给view.py,根据这个id进行sql语句的查询. 问题: 要求实时查询 解决办法: ajax查询 js页面 .on("mousedown&q ...
随机推荐
- js 实现 联动
使用jQuery实现联动效果 应用场景:收货地址 1.准备三个下拉框 <select class="changeArea" id='province'> <opt ...
- WebSocket的实现与应用
WebSocket的实现与应用 前言 说到websocket,就不得不提http协议的连接特点特点与交互模型. 首先,http协议的特点是无状态连接.即http的前一次连接与后一次连接是相互独立的. ...
- Java爬虫框架 | 爬小说
Jsoup,Java爬虫解决方案,中文文档:jsoup 不得不说Java的生态真的好,原来我以为爬虫是只能用Pyhton来写的,结果发现Java的爬虫框架不要太多…… 一分钟你就可以写 ...
- JDK1.8源码分析03之idea搭建源码阅读环境
序言:上一节说了阅读源码的顺序,有了一个大体的方向,咱们就知道该如何下手.接下来,就要搭建一个方便阅读源码及debug的环境.有助于跟踪源码的调用情况. 目前新开发的项目, 大多数都是基于JDK1.8 ...
- Python - 自学django,上线一套资产管理系统
一.概述 终于把公司的资产管理网站写完,并通过测试,然后上线.期间包括看视频学习.自己写前后端代码,用时两个多月.现将一些体会记录下来,希望能帮到想学django做web开发的人.大牛可以不用看了,小 ...
- mac安装ElasticSearch+head+node+一个例子~
1.下载ElasticSearch 官网下载链接:https://www.elastic.co/cn/downloads/past-releases(进去的可能会比较慢,网络好的情况下会好一些) 我下 ...
- Unity的弱联网Json数据传输
注意事项: 关于dictionary转json的工程中遇到一点问题:要手动添加双引号. 关于json转dictionary:同样需要手动去掉双引号,否则添加到dictionary中的字符串会带有双引号 ...
- WIZnet-io6Library下载及使用
概观 io6Library是一个IPv6集成库,可以轻松集成和管理使用WIZnet硬连线双TCP / IP堆栈控制器(WIZCHIP)产品系列的用户应用程序. io6Library用于管理依赖于用户特 ...
- ethtool工具使用实例
使用ethtool工具可以查看和修改网卡(NIC卡)设备配置,下面我们来看ethtool的具体用法. 1.显示网卡属性 ethtool命令后直接跟网卡名称,可以显示关于该网卡的属性值: # ethto ...
- JWT+Interceptor实现无状态登录和鉴权
无状态登录原理 先提一下啥是有状态登录 单台tomcat的情况下:编码的流程如下 前端提交表单里用户的输入的账号密码 后台接受,查数据库, 在数据库中找到用户的信息后,把用户的信息存放到session ...