-
我们先看一个例子:
下面是一个待匹配的字符串,我们对里面有什么一无所知,就像这样
然后我们有一个待匹配的模式串,这个我们是知道它里面有啥的
好的,我们开始匹配,在红箭头处我们发现匹配失败
我们可以得出一个什么隐含条件?
我们可以得知的是,被匹配字符串的一段是和模式串相同的。好像是废话?
那我问你,凭借这个,你能猜得到下一个偏移是不是有效的吗?或者说在哪次偏移才是有效的?记住,你现在对需要匹配的字符串其实是一无所知的,你现在仅仅能得到上面的信息。
答案其实是可以的。先用BF算法看看偏移试试?
BF是怎么偏移的?他要回退到红圈位置吧?然后当成完全不知道后面会出现啥数据一样重新开始比较。
但实际上呢?这个比较不是多余的吗?不是明知道下一个字符是B吗??
你不需要比较这一次呀,早就知道下一个字符是B,一定和A是不匹配的,这是个无效偏移呀!
我们在总结思考一下,我们该如何确定无效偏移??
因为我们的BF算法是假装不知道圈圈部分的串是啥数据,但我们是知道后面会出现什么数据的,我们知道一部分的数据应该是什么,我们可以预先知道下一次偏移是不是有效偏移。
那是不是这两个已知重合部分出现不匹配的时候,是无效偏移?只有偏移到完全匹配的时候,才是有效偏移?
是不是只有这时才是有效偏移?
发现没有,只有这个时候,从篮圈开始匹配才有意义
算法充分利用已知数据来确定了应该在哪开始。
-
为什么一定是前缀真子串和后缀真子串?
先仔细观察上面的图,你发现没有?
他们重合的地方是不是一定是串的前缀和串的后缀?我相信很多人都还不知道为啥一定是前缀和后缀,因为我当时也不清楚假设只有中缀满足了,他们重合的部分一定是不匹配的,他们重合的部分永远是前缀和后缀,要匹配的话一定要前后缀匹配。
-
辅助函数的作用
讲了这么多,其实他是怎么节省时间的呢?
对于这个算法来说,我们是不是先知道的是模式串?
那从刚刚提到的来说,我们是不是可以提前预测会出现哪些情况?比方说我在index=6的地方停了,根据上面的解释,其实就是在匹配两个完全一样的字符串吧?
字符串的来源还是从模式串里得出的哦。
于是辅助函数的作用就是,把所有可能会出现不匹配的地方进行计算,计算出在任意一个位置不匹配后,偏移到哪里才是有效偏移的下标,再把结果存储起来,一旦在匹配过程中出现不匹配,调用存储结果,直接偏移到相应位置。