BF算法
最简单直观的模式匹配算法是BF(Brute-Force)算法。
模式匹配不一定是从主串的第一个位置开始,可以指定主串中查找的起始位置pos。如果采用字符串顺序存储结构,可以写出不依赖于其他串操作的匹配算法。
最坏情况下的平均时间复杂度是O(nxm)。
【算法步骤】
KMP算法
简介:
- 这种改进算法是由 Knuth、 Morris 和 Pratt 同时设计实现的, 因此简称KMP算法。
- 此算法可以在O(n+ m)的时间数量级上完成串的模式匹配操作。
- 其改进在千:每当一趟匹配过程 中出现字符比较不等时,不需回溯 i 指针,而是利用已经得到的 ”部分匹配" 的结果将模式 向右 "滑动“ 尽可能远的一段距离后,继续进行比较。
算法实现
public class Main {public static int KMP(String str,String substr,int pos){if(pos<0 || pos>str.length()-substr.length()-1){return -1;}int[] next = new int[substr.length()];
// getNext(substr,next);getNextVal(substr,next);int i = pos;int j = 0;while (j<substr.length() && i<str.length()){if( j==-1 || str.charAt(i)==substr.charAt(j)){i++;j++;}else {j = next[j];}}if (j==substr.length()){return i - substr.length();}else {return -1;}}public static void getNext(String str,int[] next){if(str.isEmpty()){return;}next[0] = -1;next[1] = 0;int k = 0; //前缀指向的位置int i = 2; //当前next数组的值while (i<str.length()){//以当前字符为界,前缀和后缀的值一样if(k==-1 || str.charAt(k)==str.charAt(i-1)){ //next[i] = k+1;k++;i++;}else {k = next[k];}}}// 修正的nextval 数组public static void getNextVal(String str,int[] nextval){if(str.isEmpty()){return;}nextval[0] = -1;nextval[1] = 0;int k = 0;int i = 2;while (i<str.length()){if(k==-1 || str.charAt(k)==str.charAt(i-1)){if(str.charAt(k+1) != str.charAt(i)){nextval[i] = k+1;}else{nextval[i]=nextval[k+1];}k++;i++;}else {k = nextval[k];}}}public static void main(String[] args) {String str = "ababcabcdabcdefg";String sub = "abcd";int pos = 6;int x = KMP(str, sub, pos);System.out.println(x);}
}
next[0] =-1 和next[1] =0 的原因?
注意:k 的值就是我们所说的, 子串匹配失败后 i 移动(回退)到的位置
next[1] =0 : 即第二个字符匹配失败后,只能回退到第一个字符。
next数组的值,是前缀和后缀相同的长度。
假设字符串为:“aab",则charAt(0) = 'a',charAt(2-1) = 'a',next[2]=1;
假设字符串为:“aba",则charAt(0) = 'a',charAt(2-1) = 'b',next[2]=0;
参考:
Java【KMP算法】大白话式详细图文解析(附代码)_java kmp算法-CSDN博客
补充知识:
Java String类的常用方法使用方法_java中string常用方法-CSDN博客