今天,习惯性地在Matrix67大神的博客里溜达,每次溜达都能学到好多东西,记得有好几个比较经典的网站都是他的博客上提供的,而每次都有种相见恨晚的感觉。今天无意间看到一篇讲解KMP算法来进行串匹配的文章,链接如下:
串匹配在通信中应用也是相当广泛,特别是通信中的同步时候,是要进行匹配的,当然具体细节各有不同。KMP算法在Matrix67的博客中已经讲解的非常详细,对于我这种纯菜鸟都能看懂,这就是自己非常欣赏的思维讲解方式,希望大家都能好好品味下~。我写这篇文章的目的就是及时记录自己脑袋里现有的化学反应。
假设A= ‘1234545945458’,B=‘45458’,我们要来看看它们是否匹配以及在哪匹配?KMP的实现过程是这样的:我们就从A串第一个字符开始扫描,看看它是否与B的第一个字符相等,不相等就继续向后扫描A串。在本例中,A中第四个字符‘4’开始与B串第一个字符‘4’相等。紧接着,貌似我们手气很好,一口气又有‘545’相等,就当我们眼看就要匹配结束即将庆祝的时候,来了个晴天霹雳,垂死病中惊坐起般发现A接下来的字符是‘9’,而不是我们需要的‘8’。这下怎么办呢?接下来就是KMP算法的作用了:到目前为止我们已经匹配了B中的4个字符了,就差最后一个就结束整个匹配了对不,真的就是功亏一篑啊!那么我们前面做的那些都白费了吗?我们当然不能就这样放弃!!
KMP算法:我们‘一路向北’般的扫描A串,当发现有不匹配的情况出现的时候(例如上面的‘9’和‘8’),马上记录下目前的匹配长度(4),然后,我们就看看刚匹配好的这么长(4)的字符串里,我们能不能做点文章呢?我们尽量还是要保证每次尽可能长的匹配吧?刚才已经匹配了4个字符,现在有一个字符不匹配,不能一下就把我们打回地狱,把匹配长度变为0吧?我们发现4545的结构特征,从后面数的两个字符与从前面数的两个字符正好相等,这意味着什么呢?意义重大啊!!它的意思是我们不再把匹配长度变为0,它保证此时我们匹配的长度为2。再详细讲解如下:
A = 1 2 34 5 4 5 9 4 5 4 5 8
B = 4 5 4 5 8 匹配长度为4,接着扫描A,发现9与8不等。
A = 1 2 3 4 5 4 5 9 4 5 4 5 8
B = 4 5 4 5 8 由于4545的特殊结构,我们保证了此时最大的匹配是2 而不是0.目前还是扫描在9这个位置。
A = 1 2 3 4 5 4 5 9 4 5 4 5 8
B = 4 5 4 5 8 我们匹配好了2个字符,发现‘9’与‘4’不同,我们看45这个串的结构,它找不到前后相等的子串,我们就只能变成如下结构了(匹配长度回到0),继续扫描A,变为9后的下一个字符‘4’:
A = 1 2 3 4 5 4 5 9 4 5 4 5 8
B = 4 5 4 5 8 发现它正好与B第一个字符相等,匹配长度从0变为1,接着我们的运气很好,一路下来最后匹配长度等于B的长度时结束匹配。
最后,还是用Matrix67的话总结下吧:扫描字符串A,并更新可以匹配到B的什么位置。当已经匹配好的字符串有特殊结构的时候,我们更新匹配长度时可以不必从0开始(具体从多少开始,这个就是KMP算法里的预处理数组干的事,它就是完成B串的自我匹配,几乎就是KMP算法的翻版!),而当没有特殊结构时就从0开始匹配。再次向67神致敬!!