前言
设有两个串:目标串target和模式串pattern,在目标串中查找与模式串pattern相等得一个子串并确定孩子串位置的操作称为串的模式匹配。而匹配的结果有两种,如果target中存在等于pattern的子串,则匹配成功,给出孩子串在target中的位置,否则匹配失败
Brute-Force算法
算法描述:如图,该算法的核心就是在target中从begin位置,这里begin=0开始,比较ti与pi是否相等,如果有一个不相等,则begin开始从之前的下一个字符开始匹配,同时pattern中退回到第一个字符,在依次比较,知道存在相等字符,返回相应位置,可以发现该算法是一个回溯算法。
模式匹配应用
一般我们要替换或者删除相关子串时,首先就是查找是否存在此串,然后在进行相关操作
首先是替换操作
注意,String是不变类型,也就是一个新的字符串是在堆栈上又开辟了一个新空间,不是原来的对象
下面是删除操作
核心思想就是先模式匹配,然后在构造一个新的串
最后分析一下该模式匹配算法,假设模式串长度为m,可以发现他的时间复杂度为O(m);并且匹配中存在很多重复,所以算法效率是很低的
KMP算法
由之前的算法我们知道,它存在重复匹配,如之前的pattern=abc,此时p的各个字符都不相等,而在匹配时target=ababdabcd中,第一次从a匹配,到第三位不等,开始从第二位匹配,但由于第一次已经知道pi各位不等,所以第二位就不用匹配了,他肯定与第一位不等,所以可省略,而这恰恰是KMP算法的核心
next数组
next数组的作用就是研究pattern串,依次确定如果不匹配下一次target串从哪一位开始匹配。并且这样定义next数组
next[J]=-1,当j=0;
next[j]=k 当0<=k<f时且使p_0..p_k-1=p_j-k..p_j-1的最大整数
如图:pattern=”abcabc”,当j=0时,next[0]=-1;当j=1,2,3时,”a”,”ab”,”abc”都没有相同前缀子串和后缀子串next[j]=k=0;当j=4时,”abca”钟相同的前缀子串和后缀子串是”a”,所以k=1;当j=5时,为”ab”,所以k=2,依次类推
下面是KMP的算法
改进的KMP算法
当target=”aaaabcde”时,pattern=”aaaax”时,发现,a重复了,按照之前的算法,当i=5时,有重复比较四个a,所以可改进
如图:改进的nextval是在next数组基础上,这里约定的next初始值为-1,所以如j=3,与next[j]+1比较,如果相等,则其值等于next[j]+1的next值,否则,保持原next值不变
由此发现KMP算法的时间复杂度为O(n);