串(Sequence)
这里的串是指字符串:由若干个字符组成的有限序列

串匹配算法
查找一个模式串(pattern)在文本串(text)中的位置
比如:
String text = "Hello World";
String pattern = "or";
text.indexOf(pattern);//7
text.indexOf("other");//-1
几个经典的串匹配算法
蛮力
KMP
Boyer-Moore
Karp-Rabin
Sunday
tlen = text的长度
plen = pattern的长度
蛮力(Brute Force)
顾名思义,就是一个一个比较匹配:以字符为单位,从左到右移动模式串(需要查找比较的字符串),直到匹配成功。

蛮力算法有2种常见的实现思路
蛮力1


pi的取值范围[0, plen)
ti的取值范围[0, tlen)
如果patternChars[pi] == textChars[ti],则
pi++;
ti++;
去比较下一个
如果patternChars[pi] != textChars[ti],则
ti = ti - (pi - 1);//先做减法,再赋值pi=0,别反了
pi = 0;//从0开始计算
如果pi == plen
代表匹配成功
public class BruteForce01 {
public static void main(String[] args)
{
System.out.println(indexOf("Hello World", "or"));
System.out.println(indexOf("Hello World", "ww"));
}
public static int indexOf(String text, String pattern)
{
if(text == null || pattern == null) return -1;
int tlen = text.length();
int plen = pattern.length();
if (tlen == 0 || plen == 0 || tlen < plen) return -1;
char[] textChars = text.toCharArray();
char[] patternChars = pattern.toCharArray();
int pi = 0;
int ti = 0;
while (pi < plen && ti < tlen) {
if (textChars[ti] == patternChars[pi]) {
ti++;
pi++;
}else {
ti = ti - (pi - 1);
pi = 0;
}
}
return pi == plen ? ti - pi : -1;
}
}
蛮力1-优化
在发现模式串大于tlen - ti,说明待比较的text比模式串小,说明找不到了,比较就可以结束

只需要 ti < tlen修改为 ti - pi < tlen - plen;即可
蛮力2
ti是指每一轮比较中Text首个比较字符的位置


pi的取值范围[0, plen)
ti的取值范围[0, tlen - plen]
匹配失败
pi = 0;
ti++;
pi == plen
匹配成功
KMP
KMP是1977年,被三个人K某、M某、P某发布
蛮力 VS KMP

KMP对比蛮力,KMP利用了此前比较过的内容,可以一下跳过好几个
如何办到呢?
KMP有一个next表,该表是根据模式串/需要对比的串的内容生成的一张next表(一般是个数组)
假如生成的表如下:


假如匹配到E和D,两者不同,那么pi = next[pi]
也就是pi = next[7] = 3
向右移动的距离是:pi - next[pi] = 7 - next[7] = 4
博客主要介绍串匹配算法,串指字符串,算法用于查找模式串在文本串中的位置。详细阐述了蛮力算法的两种实现思路及优化方法,还介绍了KMP算法,对比了蛮力与KMP,指出KMP利用此前比较内容可跳过多个,通过next表实现。

被折叠的 条评论
为什么被折叠?



