记住这张图,getnext就是对一个已知的待匹配的串进行分析,nex【i】表示当a【i】匹配失败后我能跳到哪里,继续尝试匹配,而不是每一次失败都从头再来,先来看看代码

const int maxn = 1e5;
int net[maxn];
char a[maxn];
void get_next(int len)
{
int i = 0,j = -1;
nex[0] = -1;//别忘记初始化,和汽车的发动机一样重要
while(i < len)
{
if(j == -1 || a[i] == a[j])
{
net[++i] = ++j;
}
else
{
j = net[j];
}
}
}

j = -1是一个特殊判断代表到了头是在不能尝试匹配了得从头开始了
而a[i] = a[j]的时候,就可已更新i + 1位的net数组,他能跳的位置也就是j + 1
当a[i] != a[j]的时候,我们也是寻找的它能跳的最大(远)的点,所以先跳到net[j]去尝试匹配,……直到j=-1不能配为止,那么net[i+1]=0,也只能从头开始了

———————————————————————————————————————————————

看HDU3336

让你求每一个前缀的出现次数,是对next数组意义的考察

看那个图:是在j位置失配时能跳到的最远的位置,前提是p0 --pk-1和pj-k--pj-1相同(匹配)才能跳到k-1+1的位置再次进行匹配,也就是每一个>0的next【i】都代表0——i-1的字符串内有匹配项,我们要考虑的是断开的位置,是next数组断开的位置,如果next[i] + 1 == next[i+1]的化,代表匹配项还没结束,还在一直匹配着,我们得到结束点,然后计算前缀重复出现的次数

注意这个题是不允许交叉计算的例如ababa中aba止出现了一次,所以对我们找到的部分最长匹配串,我们是不用考虑其内部还有子匹配串的情况的 ,因为会交叉
例如a  b  a  b  a  b

  -1 0  0  1  2  3  4

面对一整个串我们只能找到的是abab这个部分最长匹配串对应的next值是4,最后结果加的4对应的分别是a,ab,(ab)a,(ab)ab,这是存在交叉

时候的运算

不存在交叉的时候最好考虑了……

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
const int maxn = 200005; int net[maxn];
char a[maxn]; void get_next(int len) //KMP原始next值
{
int i = 0, j = -1;
net[0] = -1;
while (i < len)
{
if (j == -1 || a[i] == a[j])
{
net[++i] = ++j;
}
else j = net[j];
}
}
int main()
{
int t, res,len;
scanf("%d", &t);
while(t--)
{
scanf("%d",&len); scanf("%s",&a);
get_next(len);
res = net[len] + len;
for (int i = 0; i < len ; i++)
if (net[i] > 0 && net[i] + 1 != net[i+1])
res += net[i];
printf ("%d\n", res%10007);
}
return 0;
}

这个题不大好~~就这样草草结束吧
——————————————————————————————————————————————————

再来看一道2087这是在kmp这个题比较入门,正常的匹配过程中改变一下条件就好了4

int kmp(int len1,int len2)
{
int i = 0,j = 0,cnt = 0;
while(i < len1)
{
if(j == -1 || a[i] == b[j])
{
i++;
j++;
}
else
{
j = net[j];
}
if(j == len2)
{
j = 0;
cnt++;
}
}
return cnt;
}

然后HDU1867

考的是字符串相加,一个串的前缀和另一个串的后缀可以结合,优先输出结合后长度最小的,如果长度都相等,救输出字典序最小的

一开始我做的相当的麻烦,没有一点模块化编程的想法

实现模块化就是用一个函数实现a + b 和b + a 的结果

在这里用到了指针!!
在kmp中我们求net(因为net不像是原来的题目一样求一次就过了,他需要求b再求a)

然后是改编版的kmp:因为我们寻求的是前缀和后缀相同,所以为了避免完全包含的情况入abcbc 和 bc的出现我们while的条件是i<l1:也就是母串必须遍历到头,且注意对j 重新更新为0的判断(当j == l2 && i != l1)的时候才进行

然后返回j的位置,就是,匹配后我该输出的另一个的骑士位置

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define INF 0x3f3f3f3f
#define maxn 100000+10
using namespace std; char str1[maxn], str2[maxn];
int net[maxn]; void getnet(char *x,int len)
{
int i = 0,j = -1;
net[0] = -1;
while(i < len)
{
if(j == -1 || x[i] == x[j])
{
net[++i] = ++j;
}
else j =net[j];
}
}
int kmp(char *s1,char *s2)
{
int i = 0,j = 0;
int l1 = strlen(s1),l2 = strlen(s2);
getnet(s2,l2);
while( i < l1)
{
if(j == -1 || s1[i] == s2[j])i++,j++;
else j =net[j];
if(j == l2 && i != l1)() j = 0;
}
return j;
}
int main()
{
while(~scanf("%s",str1))
{
scanf("%s",str2);
int tem1 = kmp(str1,str2);
int tem2 = kmp(str2,str1);
if(tem1 > tem2)
{
printf("%s",str1);
printf("%s\n",&str2[tem1]);
}
else if(tem1 < tem2)
{
printf("%s",str2);
printf("%s\n",&str1[tem2]);
}
else
{
if(strcmp(str1,str2) < 0)printf("%s%s\n",str1,&str2[tem1]);
else printf("%s%s\n",str2,&str1[tem2]);
}
}
return 0 ;
}

KMP回顾学习的更多相关文章

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

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

  2. [KMP]【学习笔记】

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36916   Accepted: 14904 Descript ...

  3. KMP算法学习

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

  4. Asp.net Form登陆认证的回顾学习

    asp.net网站中,我最常用的就是Form认证了,在实现登陆时,利用Form认证实现用户的访问权限,哪些页面是可以匿名登陆,哪些页面需要认证后才能访问,哪些页面不能访问等等权限.我还可在登陆时,使用 ...

  5. KMP 算法 学习 整理

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

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

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

  7. KMP算法学习(详解)

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

  8. HDU 4333 Revolving Digits [扩展KMP]【学习笔记】

    题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...

  9. 省赛在即!最大流问题回顾学习!!DInic

    Dinic是很好的算法,但是我还是从ek算法复习起步 面对最大流问题,印象最深的就是反向边的思想,他给我们提供了反悔的机会,其实现在放到实际上来想,可以相当于两边的水都流了这条边,只是方向不一样,放到 ...

随机推荐

  1. 必备 .NET - C# 脚本

    作者:Mark Michaelis | 2016 年 1 月 Link: https://msdn.microsoft.com/zh-cn/magazine/mt614271.aspx 随着 Visu ...

  2. spring AOP 注解配置

    applicationContext-resource.xml: <?xml version="1.0" encoding="UTF-8"?>< ...

  3. 在hadoop运行tensor flow

    http://www.infoq.com/cn/articles/deeplearning-tensorflow-casestudy http://www.tuicool.com/articles/a ...

  4. keras做DNN

    输入的数据集是10000行,31645列,其中前31644是特征,最后一列是标签值.训练集和测试集格式是一样的. 特征值都是0,1形式,表示有还是没有这个特征,标签值是0,1形式,2分类. impor ...

  5. 根据条件决定My97DatePicker日期控件弹出的日期格式

    代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...

  6. mahout版本兼容问题

    运行mahout in action上的cluster示例时报错:Error: Found interface org.apache.hadoop.mapreduce.Counter, but cla ...

  7. tomcat 设置内存

    SET JAVA_OPTS=-Xms256m -Xmx512m -XX:PermSize=256M -XX:MaxPermSize=512M -Xms :初始化堆内存值 -Xmx :堆内存最大值 -X ...

  8. <script language = "javascript">, <script type = "text/javascript">和<script language = "application/javascript">(转)

          application/javascript是服务器端处理js文件的mime类型,text/javascript是浏览器处理js的mime类型,后者兼容性更好(虽然application/ ...

  9. eclipse使用MAVEN打包可执行的jar包

    1.新建maven工程 注意勾选 随便填一下 建好之后工程目录如下 新建测试类与工具类,主类很简单 工具类也很简单,就是初始化了日志 maven依赖包也只有一个log4j的jar <depend ...

  10. MQ java 基础编程

    MQ java 基础编程 编写人:邬文俊 编写时间 : 2006-2-16 联系邮件 : wenjunwu430@gmail.com 前言 通过 2 个多星期对 MQ 学习,在 partner 丁 & ...