所以对于下面的子字符串
1 2 3 4 5 6 7 8 9 10 11
a b c d a b c d a b x
哪个是前缀函数?我和我的一个朋友计算了它,我们得到了不同的结果,我的是:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 2
和他的:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 1 2 0
如果我错了,那是为什么呢?
所以对于下面的子字符串
1 2 3 4 5 6 7 8 9 10 11
a b c d a b c d a b x
哪个是前缀函数?我和我的一个朋友计算了它,我们得到了不同的结果,我的是:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 2
和他的:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 1 2 0
如果我错了,那是为什么呢?
我在 java 中的 KMP 函数:
public int[] KMP(String val) {
int i = 0;
int j = -1;
int[] result = new int[val.length() + 1];
result[0] = -1;
while (i < val.length()) {
while (j >= 0 && val.charAt(j) != val.charAt(i)) {
j = result[j];
}
j++;
i++;
result[i] = j;
}
return result;
}
前缀数组的结果:
[-1, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 0]
你的两个答案都不正确。前缀函数或部分匹配表如下:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 0
您的答案在索引 10 之前是正确的。但是在最后一个索引中您做错了。部分匹配表的索引 11 的值为 0 的原因是因为没有正确的前缀可以匹配到索引 11 的字符串的任何正确的后缀。因为该位置的所有正确后缀都将以 x 结尾,并且该位置没有正确的前缀将以 x 结尾。
如果您在理解前缀函数或部分索引表的实际含义时遇到问题,可以查看此文档。它有一个很好的解释。希望能帮助到你。
前缀表应该是:
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 0
所以给出的两个版本都不正确。
对于您的表的最后一个条目
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 2
^
|
this one
正确地说,长度为 2 的后缀a b c d a b c d a b x
isb x
也必须是长度为 2 的前缀,a b
取而代之的是。
如果前缀表中的条目不为零,则相应的前缀和后缀已在下表中标记:
a 0
a b 0
a b c 0
a b c d 0
a b c d a 1
-
=
a b c d a b 2
---
===
a b c d a b c 3
-----
=====
a b c d a b c d 4
-------
=======
a b c d a b c d a 5
---------
=========
a b c d a b c d a b 6
-----------
===========
a b c d a b c d a b x 0
你的两个答案都是错误的。正确的将是
a b c d a b c d a b x
0 0 0 0 1 2 3 4 5 6 0