字符串匹配问题(string match,也叫字符串搜索)是在实际工程中经常会碰到的问题,通常其输入是主字符串(待匹配目标文本Target Text,String)和子串(模式,Pattern)组成,输出为子串在原字符串中的首次出现的位置。
通常精确的字符串搜索算法包括朴素匹配算法(也叫暴力搜索,Brute force),KMP, BM(Boyer Moore), Sunday, Rabin-Karp。通过参考一些大牛的博客,我对各字符串匹配算法有了更深的理解,整理出自己的心得。
写在前面:主字符串用S代替,长度为N;模式字符串用P代替,长度为M
朴素匹配算法
朴素匹配算法采用的思想是暴力搜索,是字符串匹配中最简单的算法,但其缺点就是十分低效。
算法过程描述:第i(1<= i <=N)次匹配,主字符串从第一个字符开始与模式串逐个进行匹配。若匹配到最后成功则返回i,若匹配到P其中某个位置不成功则立即返回,从S第i+1个字符开始再与P进行匹配。
算法分析:预处理时间:O(0) 时间复杂度:O(N*M)
算法伪代码描述和实现
// 伪代码描述和代码实现有点区别
Naive_Search(S, P)
01: for i <- 0 to N - M
02: j = 0
03: while S[i+j] == P[j] Do
04: j <- j + 1
05: if j == M return i
06: return -1
// java
public int naiveSearch(String S, String P) {
if (S == null || P == null) {
return -1;
}
int i = 0; // S的下标
int j = 0; // P的下标
int s_len = S.length();
int p_len = P.length();
while (i < s_len && j < p_len) {
if (S.charAt(i) == P.charAt(j)) {
i++;
j++;
} else {
i = i - j + 1; // 调整下一次的匹配位置i
j = 0;
}
}
if (j == p_len) { // 匹配成功
return i - j;
}
return -1;
}
参考资料:
1. 字符串匹配算法比较–airfer的专栏
2. KMP 算法(1):如何理解 KMP
3. KMP 算法(2):其细微之处
4. 如果你看不懂KMP算法,那就看一看这篇文章( 绝对原创,绝对通俗易懂)