您的位置:首页 > 其它

2015-09-26 16:49 190 查看
定义:

串是由零个或多个字符组成的有限序列,又叫字符串。

相关概念:

零个字符的串称为空串。

只包含空格的串称为空格串,注意它与空串的区别。

串中任意个数的连续字符组成的子序列称为该串的子串。包含子串的称为主串。子串在主串中的位置就是子串的第一个字符在主串中的序号。长度为n的串含有n*(n+1)/2+1(注意包含空串)。

串的模式匹配

定义:

子串的定位操作。

朴素模式匹配:

public int match(String target,String pattern){
int i=0,j=0;
while(i<target.length()&&j<pattern.length()){
if(target.charAt(i)==pattern.charAt(j)){
i++;
j++;
}
else{
i=i-j+1;
j=0;
}
}
if(j==pattern.length()){
return i-j;
}
else{
return -1;
}
}


KMP模式匹配:

关键:

假设S=“abcabcabc”,T=“abcabx”。如果T串中首字符“a”与第二位字符”b”不相等,而T串中第二位字符“b”与S串中第二位字符“b”已经判断是相等的,那么也就意味着,T串中首字符“a”与S串中的第二位“b”是不需要判断也知道它们是不可能相等了。

在朴素的模式匹配算法中,S串的i值是不断的回溯来完成的,而这种回溯其实是可以不需要的,KMP模式匹配算法就是为了让这没必要的回溯不发生。既然i值不回溯,那么要考虑的变化就是j值了。j值的变化与S串没有关系,它取决于T串的结构中是否有重复的问题。

我们把T串各个位置的j值的变化定义为一个数组next,那么next的长度就是T串的长度。next数组的定义如下所示:

当j=1时,next[j]=0
当集合{k|1<k<j,'p1...k-1'='pj-k+1...j-1'}不为空时,next[j]=Max{k}
其他情况下next[j]=1
注意:该定义是建立在假设next是从1开始计数的,但是通常情况下next是从0开始计数的,因此常在应用时将该定义转化为:
当j=0时,next[j]=-1
当集合{k|0<k<j,'p0...k-1'='pj-k...j-1'}不为空时,next[j]=Max{k}
其他情况下next[j]=0


代码实现:

//求取next数组
public int[] getNext(String T){
int[] next=new int[T.length()];
next[0]=-1;
int i=0,j=-1;
while(i<T.length()-1){
if(j==-1||T.charAt(i)==T.charAt(j)){
i++;
j++;
next[i]=j;
}
else{
j=next[j];
}
}
return next;
}
//KMP匹配
public int KMP(String S,Stirng T){
int[] next=getNext(T);
int i=0,j=0;
while(i<S.length()&&j<T.length()){
if(j==-1||S.charAt(i)==T.charAt(j)){
i++;
j++;
}
else{
j=next[j];
}
}
if(j==T.length()){
return i-j;
}
else{
return -1;
}
}


KMP算法的改进:

在计算出next值的同时,如果a位字符与它next值指向的b位字符相等,则该a位的next就指向b位的next值,如果不等,则a位的next值不变。

代码实现:

public int[] getNext(String T){
int[] next=new int[T.length()];
next[0]=-1;
int i=0,j=-1;
while(i<T.length()-1){
if(j==-1||T.charAt(i)==T.charAt(j)){
i++;
j++;
if(T.charAt(i)!=T.charAt(j)){
next[i]=j;
}
else{
next[i]=next[j];
}
}
else{
j=next[j];
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: