1.朴素模式匹配(暴力匹配)
1.1 实现思想
- 对主串 S 和模式串 T 分别设置指针 i 和 j ,假设字符串下标从 0 开始
- 初始时 i 和 j 分别指向每个串的第 0 个位置。在第 n 趟匹配开始时,i 指向主串 S 中的第 n-1 个位置,j 指向模式串T的第0个位置,然后逐个向后比较。
- 若 T 中的每一个字符都与 S 中的字符相等,则称匹配成功,否则,当遇到某个字符不相等时,i 重新指向 S 的第 n 个位置,j 重新指向 T 的第 0 个位置,继续进行第 n+1 趟匹配。
- 时间复杂度为 O(n*m),其中 n 和 m 分别为主串和模式串的长度。
1.2 具体代码实现
public class ViolenceMatch {
public static int violenceMatch(String str1,String str2){
char[] s1=str1.toCharArray();
char[] s2=str2.toCharArray();
int s1Len=s1.length;
int s2Len=s2.length;
int i=0;
int j=0;
while(i<s1Len&&j<s2Len){
if(s1[i]==s2[j]){
i++;
j++;
}else{
i=i-j+1;
j=0;
}
}
if(j==s2Len){
return i-j;
}else{
return -1;
}
}
public static void main(String[] args) {
String str1="java数据结构学习";
String str2="学习";
int index=violenceMatch(str1,str2);
System.out.println(index);
}
}
2.KMP模式匹配
2.1介绍
- kmp是一个解决如果模式串是在文本出现过,找到它最早出现位置的算法
- KMP算法就是利用之前判断过的信息,通过一个next数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过next数组找到前面匹配过的位置,省去了大量的计算时间。
2.2.部分匹配表的产生
- 部分匹配的实质就是:有时候字符串的头部和尾部会重复。比如“ABCDAB”之中,它的部分匹配值就是2(即'AB"的长度)。搜索词移动的时候,第一个“AB”向后移动4位(字符串长度-部分匹配值),就可以来到第二个“AB”的位置。
-
这样i不用回溯,j跳到前2个位置,继续匹配的过程
2.3代码实现
public class KmpMatch {
//遍历
/**
* @param str1 源字符串
* @param str2 子串
* @param next 部分匹配表
* @return 如果是-1就是没有匹配到,否则返回第一个匹配的位置
*/
public static int kmpSearch(String str1,String str2,int[] next){
for(int i=0,j=0;i<str1.length();i++){
while(j>0&&str1.charAt(i)!=str2.charAt(j)){
j=next[j-1];
}
if(str1.charAt(i)==str2.charAt(j)){
j++;
}
//找到了匹配子串的部分
if(j==str2.length()){
return i-j+1;
}
}
return -1;
}
//1.构建子串的部分匹配值表
public static int[] keepNext(String dest){
//创建一个next数组保存部分匹配值
int[] next=new int[dest.length()];
next[0]=0;//如果它的长度为1,部分匹配值就是0
for(int i=1,j=0;i<dest.length();i++)
{
while (j>0&&dest.charAt(i)!=dest.charAt(j)){
j=next[j-1];
}
if(dest.charAt(i)==dest.charAt(j)){
j++;
}
next[i]=j;
}
return next;
}
public static void main(String[] args) {
String str1="BBC ABCDAB ABCDABCDABDE";
String str2="ABCDABD";
int[] next=keepNext(str2);
System.out.println("next="+ Arrays.toString(next));
int index= kmpSearch(str1,str2,next);
System.out.println("index="+index);
}
}
参考资料:尚硅谷Java数据结构和算法