1.串的模式匹配算法
1.1 BF算法
BF算法,即暴力(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。
1.1.1 代码
int index_BF(String S,String T){
int lenS = S.length();
int lenT = T.length();
if(lenS < lenT) return -1;
int i=0,j=0;
while(i<lenS && j<lenT){
if(S.charAt(i) == T.charAt(j)){
i++;
j++;
}else{
i = i-j+1;
j = 0;
}
}
if(j >= lenT){
return i - lenT;
}
return -1;
}
1.1.2 例子
1.1.3 分析
最好的情况
假设 S=“aaaaaaaba” T=“ba”
令主串的长度为 ,子串的长度为 ,假设从主串的第 个位置开始与模式串匹配成功,则在前 趟中字符总共比较了 次;若第 趟比较成功的字符比较次数是 次,则总比较次数是 次。
最好情况下的平均比较次数为:
即最好情况下的平均时间复杂度为
最坏的情况
假设 S=“aaaaaaaab” T=“aab”
假设从主串的第 个位置开始匹配成功,则在前 趟匹配中字符总共比较了 次;若第 趟匹配成功的比较次数为 次,则总比较次数为 。
最坏情况下的平均比较次数为:
即最坏情况下的平均时间复杂度为
1.2 KMP 算法
KMP算法的改进之处在于每当一趟匹配过程中出现字符比较不等时,不需要回溯指针 i ,而是利用已得到的“部分匹配”的结果将模式向右“滑动”尽可能远的一段距离后,继续进行比较。
此算法可以在 O(n+m) 的时间数量级上完成串的模式匹配操作。
KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。
1.2.1 代码
int index_KMP(String S,String T){
int lenS = S.length();
int lenT = T.length();
if(lenS<lenT || lenT==0) return -1;
int[] next = getNext(T);
int j = -1;
for(int i=0;i<lenS;i++){
while(j>=0 && S.charAt(i)!=T.charAt(j+1)){
j = next[j];
}
if(S.charAt(i) == T.charAt(j+1)){
j++;
}
if(j == lenT-1){
return i - lenT + 1;
}
}
return -1;
}
int[] getNext(String s){
int n = s.length();
int[] next = new int[n];
int j = -1;
next[0] = j;
for(int i=1;i<n;i++){
while(j>=0 && s.charAt(i)!=s.charAt(j+1)){
j = next[j];
}
if(s.charAt(i) == s.charAt(j+1)){
j++;
}
next[i] = j;
}
return next;
}