一. 简单匹配算法
简单匹配算法,又称为朴素的模式匹配算法。简单匹配算法回溯的是i,不是j。
先来看一个简单匹配算法的例子:
public class KMP_test {
/*
* 若串 S 中从第pos(S 的下标0≤pos<StrLength(S))个字符 起存在和串 T 相同的子串,则称匹配成功,返回第一个
* 这样的子串在串 S 中的下标,否则返回 -1
*/
public static int find(String src, String target, int i) {
char[] sc = src.toCharArray();
char[] tc = target.toCharArray();
int j = 0;
while ((i + j) < sc.length && j < tc.length) {
if (sc[i + j] == tc[j]) {
j++;// 继续比较后一字符
} else {
i++; // 重新开始新的一轮匹配,i+1,j归零
j = 0;
}
}
if (j == tc.length)
return i; // 匹配成功 返回下标
else
return -1;// 串S中(第pos个字符起)不存在和串T相同的子串
}
public static void main(String[] args) {
String src = "keylovktyuy";
String target = "vkty";
System.out.println(find(src, target, 0));
// true代表找到了,false代表木有找到,
System.out.println(find(src, target, 0) == -1 ? false : true);
}
}
此算法的思想是直截了当的:将主串S中某个位置i起始的子串和模式串T相比较。即从 j=0 起比较 S[i+j] 与 T[j],若相等,则在主串 S 中存在以 i 为起始位置匹配成功的可能性,继续往后比较( j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配",即将串T向后滑动一位,即 i 增1,而 j 退回至0,重新开始新一轮的匹配。即不断回溯的是i,不是j。
例如:在串S=”abcabcabdabba”中查找T=” abcabd”(我们可以假设从下标0开始):先是比较S[0]和T[0]是否相等,然后比较S[1] 和T[1]是否相等…我们发现一直比较到S[5] 和T[5]才不等。如图:
当这样一个失配发生时,T下标必须回溯到开始,S下标回溯的长度与T相同,然后S下标增1,然后再次比较。如图:
这次立刻发生了失配,T下标又回溯到开始,S下标增1,然后再次比较。如图:
又一次发生了失配,所以T下标又回溯到开始,S下标增1,然后再次比较。这次T中的所有字符都和S中相应的字符匹配了。函数返回T在S中的起始下标3。如图: