1、用字符串1:ABCDABD 去匹配字符串2:DCABCDABEABABCDABCDABDE
2、先找到字符串1ABCDABD的前缀和后缀。 "前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。
得到部分匹配表:
字符串 | 前缀 | 后缀 | 前缀与后缀共有字符 | 共有字符长度 |
---|---|---|---|---|
A | 空集 | 空集 | 无 | 0 |
AB | B | A | 无 | 0 |
ABC | A、AB | BC、C | 无 | 0 |
ABCD | A、AB、ABC | BCD、CD、D | 无 | 0 |
ABCDA | A、AB、ABC、ABCD | BCDA、CDA、DA、A | A | 1 |
ABCDAB | A、AB、ABC、ABCD、ABCDA | BCDAB、CDAB、DAB、AB、B | AB | 2 |
ABCDABD | A、AB、ABC、ABCD、ABCDA、ABCDAB | BCDABD、CDABD、DABD、ABD、BD、D | 无 | 0 |
3、进行匹配。
(1)若第一个字符不匹配,则向后移动一个进行下一轮匹配
(2)若第二个字符以上不匹配,移动距离=前面匹配的字符数-前面匹配的字符组成的字符串的共 有字符长度。正经公式是( 移动位数 = 已匹配的字符数 - 对应的部分匹配值)这个部分匹 配值就是共有字符长度
移动后进行下一轮匹配
例子:用字符串1:ABCDABD 去匹配字符串2:DCABCDABEABABCDABCDABDE
第一次:D不匹配,移动一格
第二次:C不匹配,移动一格
第三次:D与E不匹配,前面已经匹配的字符:ABCDAB查表可知共有字符长度是2,移动位数=6- 2=4,移动4格
第四次:C与E不匹配,前面已经匹配的字符:AB查表可知共有字符长度是0,移动位数=2- 0=2,移动2格
.。。。。依此类推
求最大公共字符串长度的代码(有待理解)
public int[] getNext(String b)
{
int len=b.length();
int j=0;
int next[]=new int[len+1];//next表示长度为i的字符串前缀和后缀的最长公共部分,从1开始
next[0]=next[1]=0;
for(int i=1;i<len;i++)//i表示字符串的下标,从0开始
{//j在每次循环开始都表示next[i]的值,同时也表示需要比较的下一个位置
while(j>0&&b.charAt(i)!=b.charAt(j))j=next[j];
if(b.charAt(i)==b.charAt(j))j++;
next[i+1]=j;
}
return next;
}