1. 简言
字符串匹配的问题,可以理解为从给定符号序列中找出具有某种属性的模式的问题。最简单的字符串匹配问题,就是从给定字符序列中找出给定的字符串。
本系列文章从基本概念谈起,然后依次对单字符串匹配、多字符串匹配、模糊匹配等问题的现存算法做一归纳整理,方便大家学习。
2. 基本概念
文本 :给定的待搜索字符序列。可记为text、Text,或简写为t、T。
模式 :具有某属性的字符串,在t中可能存在0次或多次。可记为pattern、Pattern,或简写为P、Patn、p、patn等。
字符表 :字符集合,一般记为∑。t和p都定义在同一∑上。
字符串 :∑上字符组成的序列。例如对于ASCII字符表,”hello cppgp” 是字符串。
空串 :不含有任何字符的字符串称为空串。一般记为ε。
前缀 :设x、y为字符串,对于定字符串xy,称x为xy的前缀。其中x和y均可为ε。记为x⊆xy。
真前缀 :如果x为xy的前缀且满足y≠ε,则称x为xy的真前缀。记为x⊂xy。
后缀 :设x、y为字符串,对于定字符串xy,称y为xy的后缀。其中x和y均可为ε。记为x⊇xy。
真后缀 :如果x为xy的后缀且满足x≠ε,则称y为xy的真后缀。记为x⊃xy。
子串 :设x、y、z为字符串,对于定字符串xyz,称y为xyz的子串。其中x、y、z均可为ε。
真子串 :如果y为xyz的子串且满足x、y不同时为ε,则称y为xyz的真子串。
边界 :设x、y为字符串,则称x是xyx的边界。记为x=b(xyx)。
搜索窗口 :令t长度为n,p的长度为m,对于任意i≥0,i+m≤n,称t[i..i+m]为一个搜索窗口。
3. 单字符串匹配
在所有单字符串匹配的算法中,都存在搜索窗口的概念,搜索窗口沿着text从左向右移动,搜索过程在搜索窗口内进行(如Figure-01所示)。根据搜索窗口内移动方式的不同,单字符串匹配算法可以归纳为三类:前缀搜索、后缀搜索、子串搜索。
前缀搜索:
在搜索窗口内从前向后逐个读入字符,获取搜索窗口和模式串的最长公共前缀。当最长前缀等于模式串长度时,匹配成功。暴力搜索、KMP、都属于该类。如Figure-02所示。
后缀搜索:
在搜索窗口内从后向前逐个读入字符,获取搜索窗口和模式串的最长公共后缀。当最长后缀等于模式串长度时,匹配成功。Boyer-Moore、Horspool、Sunday、都属于该类。该类算法通常具有亚线性的时间复杂度。如Figure-03所示。
子串搜索:
在搜索窗口内从后向前逐个读入字符,搜索满足如下条件的最长字符串u:u是搜索窗口的后缀,同时也是模式串的子串。与后缀搜索算法一样,使用这种搜索方法的算法也具有亚线性的平均时间复杂度。如Figure-04所示。