定义、基本操作
1.定义
串,即字符串(String)是由零个或多个字符组成的有限序列。一般记为 S = ‘a1a2······an’ (n ≥0)
S是串名,单引号括起来的字符序列是串的值;ai可以是字母、数字或其他字符;串中字符的个数n称为串的长度。n = 0时的串称为空串(用∅表示)
子串:串中任意个连续的字符组成的子序列。
主串:包含子串的串。
字符在主串中的位置:字符在串中的序号。
子串在主串中的位置:子串的第一个字符在主串中的位置 。
2.基本操作
串的基本操作,如增删改查等通常以子串为操作对象
y = f(x)
字符集:函数定义域
编码:函数映射规则 f
y:对应的二进制数
存储结构
1.顺序存储
2.链式存储
朴素模式匹配算法
模式串:给一串字符,让你找主串里有没有
朴素模式算法就是一个一个找,这个不行就从下一个子串开始
KMP算法
发生不匹配的时候,找里面可以期待的子串(已经匹配了的里面找,把i回退到那里就可以了),j就跟着退
用一个数组next[7]装在各个情况下j应该退到的位置
i除了第一个就错(第一个就错,j会变为0,然后i和j统一向后移一位,因为i要向后移一位,为了方便和匹配成功弄成一样的的代码,所以j先变为0,然后++变成1),还有匹配成功,其他时候是不动的(避免了很多次查找)
这里的j=0就是当第一位就错的时候,j会变成0,然后在此次判定之后i和j都向后移一位,再继续(这样方便写代码)
求next数组
i和j都不动,相当于让模式串自己往前动到一个合适的位置,然后看此时j指向哪就行了
这个也很好的说明了前面j为什么指向0,指向0之后i和j都要向后一位(perfect)
几个练习题:
KMP 算法平均时间复杂度:O(n+m)
其中,求next数组为O(m),KMP算法为O(n)
,两者相加(模式串长度为m,next数组求m次,所以为O(m),KMP长度为n,每次只要不对就直接跳到next(j),i也不会动,所以只需要n次,时间复杂度就为O(n))
KMP算法优化——nextval数组
nextval的求法:同,变(变成nextval【next】);不同,不变。(比较j和next所指的字母,nextval第一位一直为0)
如下面这个图,第一位为0;第二位的next为1,第二位是b,和a不一样,所以nextval和next一样;第三位的next是1,第三位是a,一样,所以nextval=nextval[1]=0;第四位和第二位比较,相同,nextval=nextval【2】=1;第五位和第三位比较,相同,nextval=nextval【3】=0;第六位和第四位比较,不同,维持原状
所以求nextval前还是要先求出next数组,然后进行优化
虽然是l,已经不是g了,但是KMP算法依然要让j指向1再比较一次(无意义)
KMP算法还是存在问题,如图虽然后面是个c,但是还是会进行几次无意义的比较,这就是优化的点