扩展KMP(占位)
先放代码。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N = ;
int next[N],extand[N];
void getnext(char *T){// next[i]: 以第i位置开始的子串 与 T的公共前缀
int i,length = strlen(T);
next[] = length;
for(i=;i<length-&&T[i]==T[i+];i++);
next[]=i;
int a=;
for(int k = ; k < length; k++){
int p = a+next[a]-, L = next[k-a];
if( (k-)+L >= p ){
int j = (p-k+)>? (p-k+) : ;
while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较
next[k] = j, a = k;
}
else next[k] = L;
}
}
void getextand(char *S,char *T){
memset(next,,sizeof(next));
getnext(T);
int Slen = strlen(S), Tlen = strlen(T), a = ;
int MinLen = Slen>Tlen?Tlen:Slen;
while(a<MinLen && S[a]==T[a]) a++;
extand[] = a, a = ;
for(int k = ; k < Slen; k++){
int p = a+extand[a]-, L = next[k-a];
if( (k-)+L >= p ){
int j = (p-k+)>? (p-k+) : ;
while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++;
extand[k] = j;a = k;
}
else extand[k] = L;
}
} int main(){
char s[N],t[N];
while(~scanf("%s %s",s,t)){
getextand(s,t);
for(int i = ; i < strlen(t); i++)
printf("%d ",next[i]);
puts("");
for(int i = ; i < strlen(s); i++)
printf("%d ",extand[i]);
puts("");
}
return ;
}
下标从1开始。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N = ;
int next[N],extand[N];
char S[N],T[N];
void getnext(){// next[i]: 以第i位置开始的子串与T的公共前缀长度
int i,length=strlen(T+);
next[]=length;
for(i=;i+<length&&T[i+]==T[i+];i++);
next[]=i;
int a=; //!
for(int k=;k<=length;k++){//长度+1,位置-1。
int p=a+next[a]-, L=next[k-a+];
if(L>=p-k+){
int j=(p-k+)>?(p-k+):;//中断后可能是负的
while(k+j<=length&&T[k+j]==T[j+]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较
next[k]=j, a=k;
}
else next[k]=L;
}
}
void getextand(){
memset(next,,sizeof(next));
getnext();
int Slen=strlen(S+),Tlen=strlen(T+),a=;
int MinLen=Slen>Tlen?Tlen:Slen;
while(a<MinLen&&S[a+]==T[a+]) a++;
extand[]=a, a=;
for(int k=;k<=Slen;k++){
int p=a+extand[a]-,L=next[k-a+];
if(L>=p-k+){
int j=(p-k+)>?(p-k+):;
while(k+j<=Slen&&j<Tlen&&S[k+j]==T[j+]) j++;
extand[k]=j;a=k;
}
else extand[k]=L;
}
} int main(){
while(~scanf("%s %s",S+,T+)){
getextand();
for(int i=;i<=strlen(T+);i++)
printf("%d ",next[i]);
puts("");
for(int i=;i<=strlen(S+);i++)
printf("%d ",extand[i]);
puts("");
}
return ;
}
扩展KMP(占位)的更多相关文章
- 扩展KMP算法
一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...
- 扩展KMP --- HDU 3613 Best Reward
Best Reward Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权 ...
- KMP和扩展KMP
文章网上太多这里提一下代码细节: KMP: scanf("%s\n",s); scanf("%s\n",t); int ls=strlen(s),lt=strl ...
- UVA5876 Writings on the Wall 扩展KMP
扩展KMP的简单题. #include<stdio.h> #include<string.h> #define maxn 51010 char s[maxn],t[maxn]; ...
- hdu4333 扩展KMP
慢慢研究可以发现,可以用扩展kmp来求.由于扩展kmp的next[]只有一部分,当前位子前面那部分和母串的后部分,所以可以将字符串复制接在后面一次. 先求如果next[]>0&& ...
- 扩展KMP
刘雅琼论文 http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html 论文讲的非常详细. 给定母串S,子串T,n=strlen(S),m=st ...
- HDU 3336 扩展kmp
题目大意: 找到字符串中所有和前缀字符串相同的子串的个数 对于这种前缀的问题,通常通过扩展kmp来解决 其实吧这是我第一次做扩展kmp的题目,原来确实看过这个概念,今天突然做到,所以这个扩展kmp的模 ...
- acdream1116 Gao the string!(扩展KMP)
今天是字符串填坑的一天,首先填的第一个坑是扩展KMP.总结一下KMP和扩展KMP的区别. 在这里s是主串,t是模式串. KMP可以求出的是以s[i]为结尾的串和 t前缀匹配的最长的长度.假如这个长度是 ...
- hdu 4333(扩展kmp)
题意:就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数字中,比原数字小的,相等的,大的分别有多少个.比如341-->134-->413-->3 ...
- 扩展KMP题目
hdu4333 /* 题意:字符串s[0..n-1],每次把最后一个字符放到前面,求形成的字符串比最初串分别小,相同,大于的个数 因为是为了练习扩展KMP所以肯定是扩展KMP, 为了循环方便,在后面复 ...
随机推荐
- POJ 3461 kmp 应用
题意:求匹配串在文本中出现次数,KMP应用,理解了就OK了,每次匹配成功就累加次数,开始的时候超时, 由于在处理每次成功的时候让i=i-len2+1,相当于回溯了,后来一想,本次成功,相当于" ...
- HDU 1358字符串循环节问题 ,next数组
求字符串循环节,要求每前i个字符串前缀是否循环,有的话打印出来. 我对j=next[i]数组(未优化,从0开始,第一个为-1,)理解:字符s[i]的前面的字符串,最长的相同的前缀和后缀 的长度,因此, ...
- PSO(Thepopularity-similarity-oplimization) modol
PSO(Thepopularity-similarity-oplimization) modol 在这篇文章里,我们试图将社交关系构成的网络结构从纷繁复杂的具体场景.细节条件中剥离出来,单单从个体间连 ...
- springboot整合mybatis+jetty笔记以及遇到的问题
图文创建一个springboot Demo(IDEA创建)+目录图+返回json springboot创建参考 pom.xml <dependencies> <!--<depe ...
- 关于PDF的读取与绘制
本文方法参考了:官方文档.见A function that draw a PDF page的代码部分: void MyDisplayPDFPage (CGContextRef myContext, s ...
- 使用JavaScript进行进制转换将字符串转换为十进制
JS 是一个很神奇的语言,内制的的很多函数可以帮我们进行数(进)制转换: JS中可以直接使用16进制: var a = 将任意进制字符串转换为十进制,如二进制,八进制,十六进制, 第二数数不写即为最常 ...
- 解决vs2005调试时出现未载入符号的问题
首先在以下的网址下载相应系统的符号包 http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx 下载完之后安装到一个文件夹比方D: ...
- BUPT复试专题—中序遍历序列(2013)
题目描述 给出一个序列,判断该序列是不是某二叉搜索树的中序遍历序列,如果是输出"Yes",否则输出"No".一颗带权二叉树是一颗二叉搜索树(二叉排序树),当且仅 ...
- vim编码方式配置的学习和思考
哎呀呀,今天9月30号,立即就要十一长假了,心里还有点小小浮躁.工作已经基本做完,想成为技术大牛怎么能够如此浮躁.为了应付浮躁的心灵,决定写一篇小博,平静一把. 今天一个配置文件须要有中文,而且同事是 ...
- java解析xml的方式DOM,SAX,DOM4J,JDOM,StAX
1)DOM(JAXP Crimson解析器)DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在树中寻找 特定信息. ...