KMP和扩展KMP
文章网上太多这里提一下代码细节:
KMP:
scanf("%s\n",s);
scanf("%s\n",t);
int ls=strlen(s),lt=strlen(t);
f[]=f[]=;
for(int i=;i<lt;++i)
{
int j=f[i];
while(j&&t[j]!=t[i]) j=f[j];
if(t[j]==t[i]) f[i+]=j+;else f[i+]=;
}
int j=;
for(int i=;i<ls;++i)
{
while(j&&t[j]!=s[i]) j=f[j];
if(t[j]==s[i]) ++j;
if(j==lt) printf("%d\n",i-lt+);
}//Kmp的代码比较简单理解了就不会出错
扩展KMP:
scanf("%s\n",s);
scanf("%s\n",t);
int ls=strlen(s),lt=strlen(t);
next[]=lt;
next[]=lt-;//第一个注意点:对自己匹配的时候是要从第1个位置开始暴力,而不是第0个
for(int i=;i<lt-;++i)
if(t[i]!=t[i+])
{
next[]=i;
break;
}
int k=;
for(int i=;i<lt;++i)
{
int p=k+next[k]-,l=next[i-k];
if(i+l<=p) next[i]=l;
else
{
int j=p-i+;
if(j<) j=;//注意这里不加会爆掉而且很难找出来
while(i+j<lt&&t[i+j]==t[j]) ++j;
next[i]=j;
k=i;
}
}
ex[]=lt;//两个串匹配则是从第0个位置开始暴力
for(int i=;i<lt;++i)
if(s[i]!=t[i])
{
ex[]=i;
break;
}
k=;
for(int i=;i<ls;++i)
{
int p=k+ex[k]-,l=next[i-k];
if(i+l<=p) ex[i]=l;
else
{
int j=p-i+;
if(j<) j=;//同上
while(i+j<ls&&j<lt&&s[i+j]==t[j]) ++j;
ex[i]=j;
k=i;
}
}
这里来手推一下扩展Kmp:
设p表示S到达的最远点,而p是由k更新到的,故p=k+ex[k]-1
故s[k..p]==t[0..p-k]
我们要求的是ex[i],所以要找出s[i]开头的一些关系,又注意到i>k,故s[i..p]==t[i-k..p-k]
而又想到应该是s[i..p]==t[0..?],因为匹配的是从0开始的,所以就涉及到了t[i-k..?]和t[0..?]的自身匹配,故引进next[i-k]表示t和t自己匹配(与ex[]一样,只不过ex[]保存的是两个字符串的匹配),设其为L,则有t[i-k..i-k+l-1]==t[0..l-1]
这里考虑:①i-k+l-1<p-k,则说明匹配到的最远的在最远点P之内,故不会涉及到我们不知道的领域,所以肯定ex[i]=l;
②i-k+l-1>=p-k,这就说明s[i..p]==t[0..p-i],那么接下来就从s[p+1]和t[p-i+1]开始暴力判断,并维护k和p
KMP和扩展KMP的更多相关文章
- KMP和扩展KMP【转】
这种东西基本上在纸上自己推导一下就能做出来XD 转发注明出处 KMP 给出两个字符串A(称为模板串)和B(称为子串),长度分别为lenA和lenB,要求在线性时间内,对于每个A[i] (0<=i ...
- KMP与扩展KMP
原文转自:http://www.cppblog.com/MatoNo1/archive/2011/04/17/144390.aspx KMP:给出两个字符串A(称为模板串)和B(称为子串),长度分别为 ...
- Manacher模板,kmp,扩展kmp,最小表示法模板
*N]; //储存临时串 *N];//中间记录 int Manacher(char tmp[]) { int len=strlen(tmp); ; ;i<len;i++) { s[cnt++]= ...
- KMP && Manacher && 扩展KMP整理
KMP算法: kmp示例代码: void cal_next(char *str, int *next, int len) { next[0] = -1;//next[0]初始化为-1,-1表示不存在相 ...
- kmp模板 && 扩展kmp模板
kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...
- 【kmp或扩展kmp】HDU 6153 A Secret
acm.hdu.edu.cn/showproblem.php?pid=6153 [题意] 给定字符串A和B,求B的所有后缀在A中出现次数与其长度的乘积之和 A和B的长度最大为1e6 方法一:扩展kmp ...
- KMP 、扩展KMP、Manacher算法 总结
一. KMP 1 找字符串x是否存在于y串中,或者存在了几次 HDU1711 Number Sequence HDU1686 Oulipo HDU2087 剪花布条 2.求多个字符串的最长公共子串 P ...
- 666 专题三 KMP & 扩展KMP & Manacher
KMP: Problem A.Number Sequence d.求子串首次出现在主串中的位置 s. c. #include<iostream> #include<stdio.h&g ...
- kmp与扩展kmp模板
kmp 1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include & ...
随机推荐
- andriod增、删、改、查
将数据库的增删改查单独放进一个包 */ package com.itheima28.sqlitedemo.dao; import java.util.ArrayList; import java.ut ...
- Oracle VirtualBox 使用桥接网络完成主机和虚拟机之间的双向通讯
最近刚换了新的笔记本电脑,终于使用上intel i7处理器,可以使用硬件虚拟化技术安装系统.配置如下: 主机 ThinkPad P50s OS Window 10 虚拟机软件 Orac ...
- linux设置tomcat开机启动
[root@iZ94j7ahvuvZ ~]# cd /etc/rc.d/ [root@iZ94j7ahvuvZ rc.d]# cat rc.local #!/bin/sh # # This scrip ...
- NOIP2008普及组 题解 -SilverN
T1 ISBN号码 题目描述 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1位识别码和3位分隔符, 其规定格式如“x-xxx-xxxxx-x”,其中符号“-”就是分隔符( ...
- 双向广搜 codevs 3060 抓住那头奶牛
codevs 3060 抓住那头奶牛 USACO 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 农夫约翰被告知一头逃跑奶牛 ...
- UVALive 6255 Kingdoms --状态搜索
题意:n个国家,给出国家间相互的债务关系,每个国家如果债务>收入就要破产,破产后该国的所有债务关系全部清除,第一个破产的国家不同有可能造成最后的没破产的国家的不同,问哪些国家有可能成为独自存活的 ...
- Spring整合Hibernate详细步骤
阅读目录 一.概述 二.整合步骤 回到顶部 一.概述 Spring整合Hibernate有什么好处? 1.由IOC容器来管理Hibernate的SessionFactory 2.让Hibernate使 ...
- 注册其它地区Apple ID
不同地区Apple Id需求 iPhone 最近换上了iPhone,想要下载其它国家地区的游戏,需要登录该国的Apple Id才能在itunes里下载. 下面记录一下我注册日本地区的Apple Id过 ...
- VS 扩展推荐
Visual Studio 工欲善其事,必先利器.本着这样的观念,对于经常使用的工具,我喜欢去研究研究,帮助我提高效率. Visual Studio Microsoft Visual Studio(简 ...
- 会动的大风车(css3)
今天用css3的写了一个会动的大风车,使用translate和rotate布局,使用animation制作动画效果:分享给大家 <!DOCTYPE html> <html lang= ...