概述
KMP字符串匹配算法详解与java实现
问题描述
所谓字符串匹配,即是给定一个模式字符串pattern,在另一个字符串str中寻找首次出现的索引。若str中不存在pattern字符串,则返回-1;
KMP的整体思路
1、利用模式串pattern计算生成数组next;数组next决定了在某一位字符不匹配时,应该回溯到模式串的哪一个位置。
2、根据next数组在目标字符串str中搜索模式串pattern。
先验知识
在这里,先讲一下前后缀的概念便于后面理解。
"前缀"指除了最后一个字符以外,一个字符串的全部头部组合;
"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。
"A"的前缀和后缀都为空集;
"AB"的前缀为[A],后缀为[B];
"ABC"的前缀为[A, AB],后缀为[BC, C];
"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D];
"ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A];
具体实例
假设 pattern=“bcbcbc”,str=“bcbcbacbcbcbc”
1、首先我们根据模式串pattern计算生成next数组
i | string | 前缀 | 后缀 | 最长公共元素 | next[i] |
---|---|---|---|---|---|
0 | b | -- | -- | -- | 0 |
1 | bc | b | c | -- | 0 |
2 | bcb | b,bc | b,cb | b | 1 |
3 | bcbc | b,bc,bcb | c,bc,cbc | bc | 2 |
4 | bcbcb | b,bc,bcb,bcbc | b,cb,bcb,cbcb | bcb | 3 |
5 | bcbcbc | b,bc,bcb,bcbc,bcbcb | c,bc,cbc,bcbc,cbcbc | bcbc | 4 |
以下为该部分的代码
public int[] getNext(String pattern){
int[] next=new int[pattern.length()];
if(pattern.length()==0){
return next;
}
next[0]=0;
int k=0;
for(int i=1;i<pattern.length();i++){
while(k>0 && pattern.charAt(i)!=pattern.charAt(k)){
k=next[k-1];
}
if(pattern.charAt(i)==pattern.charAt(k)){
k++;
}
next[i]=k;
}
return next;
}
2、根据next数组在目标字符串str中搜索模式串pattern
public static int search(String str, String pattern){
//当模式串为空串时,返回0
if(pattern.length()==0) {return 0;}
//当目标字符串为空串时,返回-1
if(str.length()==0) { return -1;}
int[] next=getNext(pattern);
for(int i=0,j=0;i<str.length();i++){
//当前字符(模式串中第j个字符)不匹配时,要回退到前一位(第j-1个字符)的next值的位置
while(j>0&&str.charAt(i)!=pattern.charAt(j)){
j=next[j-1];
}
//匹配,j指向模式串的下一个字符位置
if(str.charAt(i)==pattern.charAt(j)){
j++;
}
//当j等于模式串的长度时,匹配成功,返回匹配的开始位置
if(j==pattern.length()){
return i-j+1;
}
}
return -1;
}
}
结论
两部分的代码很相似,因为他们都是一个字符串针对模式串pattern的匹配,第一部分是模式串针对自己的匹配,第二部分是目标字符串str针对模式串的匹配。
参考
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
《算法导论》第3版 第32章字符串匹配
最后
以上就是害怕小馒头为你收集整理的KMP字符串匹配算法详解与java实现的全部内容,希望文章能够帮你解决KMP字符串匹配算法详解与java实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复