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 ...
随机推荐
- How to extract WeChat chat messages from a smartphone running Android 7.x or above
A friend of mine she was frustarted in extracting WeChat chat messages from suspect's smartphone run ...
- SCI论文的时态
如果有的杂志对时态有要求,则以下所述都没有用了. 有些杂志也会专门有些比较“特别”的要求,比如Cell,要求Abstract全部使用一般现在时. 英语谓语动词时态共有16种,在英文科技论文中用得较为频 ...
- Adapter适配器模式--图解设计模式
第二章: Adapter 模式 Adapter模式分为两种: 1.类适配器模式 2.委托适配器 我看的是<图解设计模式>这本书,这小鬼子说的话真难懂,只能好好看代码理解. 先说适配器模式要 ...
- L1063 能量项链
1 #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = a; i <= b ...
- 免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作简易流量爬虫
前言 我们之前的爬虫都是模拟成浏览器后直接爬取,并没有动态设置IP代理以及UserAgent标识,本文记录免费IP代理池定时维护,封装通用爬虫工具类每次随机更新IP代理池跟UserAgent池,并制作 ...
- IntelliJ IDEA 激活(最新)
注:此文以 Mac 为例,Windows 的激活方法也大同小异.如果不差钱的话,建议购买正版! 1.下载安装 直接通过下面的链接到官网下载最新的 Ultimate 版本即可: https://www. ...
- mysql主从不同步处理过程分享
背景 8月7日15:58收到报障数据库出现不同步:数据库共四台,分别为10.255.70.11,10.255.70.12,10.255.70.13,10.255.70.14(ip为虚拟ip) 数据库 ...
- temperatureConversion1
(原题:https://www.python123.io/student/courses/934/groups/8102/problems/programmings/6078) Solution: # ...
- 2019牛客暑期多校训练营(第十场)F-Popping Balloons
>传送门< 题意:现在给你n个点 ,让你横着划三条线间距为r 然后竖着划三条线间距同样为r ,求经过最多的点数 思路:比赛看到这题的时候觉得能做,但是一看时间限制是5s,搞得我有不敢去碰了 ...
- 后端开发实践系列之三——事件驱动架构(EDA)编码实践
在本系列的前两篇文章中,笔者分别讲到了后端项目的代码模板和DDD编码实践,在本文中,我将继续以编码实践的方式分享如何落地事件驱动架构. 单纯地讲事件驱动架构(Event Driven Architec ...