字符串匹配 BF(Brute Force)
400 Words|Read in about 2 Min|本文总阅读量次
经典的字符串匹配算法,BF(Brute Force)算法。
0准备
1int main() {
2 string s = "abababc";
3 string p = "abc";
4 string s1 = "abcdefgabcdee";
5 string p1 = "abcdex";
6 string s2 = "00000000000000000000000000000001";
7 string p2 = "00000001";
8 cout << BF(s, p) << endl;
9 cout << BF(s1, p1) << endl;
10 cout << BF(s2, p2) << endl;
11}
BF(Brute Force)算法
BF(Brute Force)算法
又叫暴力匹配算法或者朴素匹配算法
思路很简单:在主串中取前下标为[0,m-1]这m个字符的子串和模式串逐个字符逐个字符比较,如果完全一样就结束并返回下标;如果有不一样的,那么主串中的子串后移一位,主串中[1,m]这个子串和模式串继续比较,… ,主串中[n-m,n-1]这个子串和模式串继续比较。主串中长度为m的子串有n-m+1个。
C的版本
1int BF(string& s, string& pattern)
2{
3 int n = s.length(), m = pattern.length();
4 for (int i = 0; i < n - m + 1; i++)
5 {
6 int j = 0;
7 for (; j < m; j++)
8 {
9 if (i + j >= n || s[i + j] != pattern[j])
10 break;
11 }
12 if(j == m)
13 {
14 //匹配到了,返回主串中的下标
15 return i;
16 }
17 }
18 //匹配不到
19 return -1;
20}
举例2,字符串"abcdedgabcdee"
中匹配字符串"abcdex"
。在i = 0
会做一个匹配,但是最后一个字符匹配不上,只能继续遍历,在i = 7
的时候会再一次匹配,但是最后一个字符匹配不上,最终返回-1
。
i = 0
i = 1
i = 7
举例3可以发现,当32位的uint32
型数值的字符串中匹配uint8
型数值的字符串就会比较繁琐,从i = 0
开始,直到i = 24
位置才能够完全匹配,这就是BF的暴力求解法。
i = 0
i = 1
i = 24
Java版本
1//String.java#indexOf
2//jdk源码
3static int indexOf(char[] source, int sourceOffset, int sourceCount,
4 char[] target, int targetOffset, int targetCount,
5 int fromIndex) {
6 if (fromIndex >= sourceCount) {
7 return (targetCount == 0 ? sourceCount : -1);
8 }
9 if (fromIndex < 0) {
10 fromIndex = 0;
11 }
12 if (targetCount == 0) {
13 return fromIndex;
14 }
15
16 char first = target[targetOffset];
17 int max = sourceOffset + (sourceCount - targetCount);
18
19 for (int i = sourceOffset + fromIndex; i <= max; i++) {
20 /* Look for first character. */
21 if (source[i] != first) {
22 while (++i <= max && source[i] != first);
23 }
24
25 /* Found first character, now look at the rest of v2 */
26 if (i <= max) {
27 int j = i + 1;
28 int end = j + targetCount - 1;
29 for (int k = targetOffset + 1; j < end && source[j]
30 == target[k]; j++, k++);
31
32 if (j == end) {
33 /* Found whole string. */
34 return i - sourceOffset;
35 }
36 }
37 }
38 return -1;
39}
BF算法总结
最坏的情况下,在第一个for循环里,i 从0到n-m走满共n-m+1次,第二个for循环里,j 从0到m-1走满共m次,因此最坏的情况下时间复杂度为O(n*m),上述例子中
string a2 = "00000000000000000000000000000001"
,string p2 = "00000001"
;所有n-m+1个子串都要走完,并且每次和模式串比较都要比较m次,总共比较n-m+1次,最坏的时间复杂度为o((n - m + 1) * m)BF算法最大的优点就是简单,代码不容易出错,在主串和模式串的长度都不大的时候还是比较实用的。