之前在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算法学习 与 传参试验(常回来看看)的更多相关文章

  1. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  2. KMP算法学习

    kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(n ...

  3. KMP 算法 学习 整理

    我自己整理的KMP算法的PDF文件:http://pan.baidu.com/s/1o8yKIi2提取密码:8291 别的就不多说啥了,感谢来自海子 博客园的 资料--

  4. KMP算法学习(详解)

    kmp算法又称“看毛片”算法,是一个效率非常高的字符串匹配算法.不过由于其难以理解,所以在很长的一段时间内一直没有搞懂.虽然网上有很多资料,但是鲜见好的博客能简单明了地将其讲清楚.在此,综合网上比较好 ...

  5. 字符串匹配的BF算法和KMP算法学习

    引言:关于字符串 字符串(string):是由0或多个字符组成的有限序列.一般写作`s = "123456..."`.s这里是主串,其中的一部分就是子串. 其实,对于字符串大小关系 ...

  6. KMP 算法学习

    KMP算法是用来做字符串匹配的.关于字符串匹配,最简单最容易想到的方法是暴利查找,使用双重for循环处理. 该方法的时间复杂度为O((n-m+1)*m) (n为目标串T长度,m为模式串P长度, 从T中 ...

  7. KMP算法学习以及小结(好马不吃回头草系列)

    首先请允许我对KMP算法的三位创始人Knuth,Morris,Pratt致敬,这三位优秀的算法科学家发明的这种匹配模式可以大大避免重复遍历的情况,从而使得字符串的匹配的速度更快,效率更高. 首先引入对 ...

  8. KMP算法 学习例题 POJ 3461Oulipo

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37971   Accepted: 15286 Description The ...

  9. Django学习----js传参给view.py

    需求: 散点图中每选择一个点,获取到id之后传给view.py,根据这个id进行sql语句的查询. 问题: 要求实时查询 解决办法: ajax查询 js页面 .on("mousedown&q ...

随机推荐

  1. zabbix监控WEB网站性能

    一直在纠结用什么实例来给大家演示呢?想来想去还是官方的好,那我们怎么用zabbix监控web性能和可用性呢?我们这边分为几个步骤:打开网站.登陆.登陆验证.退出,一共4个小step,看实例. 检测流程 ...

  2. ipv6的连接

    基础知识不说了,网上一大堆! 基本内容不说了,写字太累了! 只说三点细节,记住就行: 1.ff开头的是多播地址,只能用于udp多播 2.fe80开头的是本地link地址,不管ping也好,connec ...

  3. Go中的函数和闭包

    函数参数和返回值的写法 如果有多个参数是同一个类型,可以简略写: func testReturnFunc(v1,v2 int)(int,int) { x1 := 2 * v1 x2 := 3 * v2 ...

  4. 如何成为PHP程序员?

    当今,互联网的蓬勃发展,移动互联网的火热,以及国家提出的“互联网+”.这些趋势可以让我们明显的感觉到互联网的重要,不可替代.网站也是大家最早接触,最早认识的一种新事物.谈到网站,无非最长脸的莫过于PH ...

  5. SAP无法激活表问题

    因为修改了表结构导致无法激活,刚开始以为是数据库没有调整,然后试着运行SE14,发现还是报错 这个时候就要看看数据库服务器时候正常,输入事务码ST04,查看概览,发现磁盘已满 登录HANA Studi ...

  6. 暂停研发surging,是否继续维护!

    前言 surging从2017 年开始,2 年来利用业余时间为 surging语言添砖加瓦. 这种活雷锋行为并没有得到开发者们的理解,很多人甚至用命令的口吻,灵魂拷问方式要求活雷锋们再苦再累也得免费为 ...

  7. 基于UDP的socket tcp和udp的区别(小白进击篇)

    目录 16.基于udp协议的socket通信 为什么udp不会有粘包现象 DGRAM datagram#数据报文 发送sento (发送的信息,发送给的地址) 接收revefrom 客户端 服务端 t ...

  8. python 之os模块用法大全

    Python的标准库中的os模块包含普遍的操作系统功能.这个模块的作用主要是提供与平台无关的功能.也就是说os模块能够处理平台间的差异问题,使得编写好的程序无需做任何改动就能在另外的平台上运行 这边给 ...

  9. Java Selenium (十二) 操作弹出窗口 & 智能等待页面加载完成 & 处理 Iframe 中的元素

    一.操作弹出窗口   原理 在代码里, 通过 Set<String> allWindowsId = driver.getWindowHandles(); 来获取到所有弹出浏览器的句柄, 然 ...

  10. 关于《Selenium3自动化测试实战--基于python语言》

    2016年1月,机缘巧合下我出版了<Selenium2自动化测试实战--基于python语言>这本书,当时写书的原因是,大部分讲Selenium的书并不讲编程语言和单元测试框,如果想在项目 ...