1:问题描述:给定文本串,长度n;给定模式串,长度m,求模式串在文本串中出现的起始位置
2:几种字符串匹配算法:处理时间 = 预处理时间 + 匹配时间
算法 预处理时间 匹配时间 朴素的模式匹配 0 o((n-m+1)*m) Rabin-Karp o(m) o((n-m+1)*m) 有限自动机 o(状态数*字符数) o(n) KMP 0(m) o(n)
Rabin-Karp原理:
假设文本串为10进制数字{0,1,2...9}组成的字符串,模式串长度为m: 将模式串转化为数,模13,得余数x; 将文本串的所有子串{i,i+1,i+2...i+m-1}转化为数,模13,得余数y[i]; 求文本串子串对应数的过程可以迭代实现:将{i-1,i,i+1...i+m-2}子串对应的数去掉高位,左移(乘以10),加上(i+m-1)位的数字; 比较:若Y[i] = x,再考虑文本串以i为起始,长度为m的子串是否和模式串匹配; 分析:预处理时间为o(m) 最坏时间复杂度为o((n-m+1)*m) 当基于某种假设,平均运行时间会比较好些
有限状态自动机原理:
假设状态集{1,2,3}:1为开始状态,3为终止状态; 字符集{'a','b','c','d'} ; 状态转换函数:F(i状态,接收字符) = j状态; 为模式串初始化有限状态自动机;:用矩阵x存储,行值i为状态(i=1,2,3),列值j为输入字符(j='a','b','c','d'),x[i][j] = 抵达状态,当不可达时,抵达状态为-1 匹配:根据矩阵x,扫描文本串,得到状态列表,当某状态为终止状态,即模式串出现在了文本串。
KMP原理:
改进朴素的模式匹配: 朴素的模式匹配中,模式串匹配成功i位,第i+1位匹配失败((i+1)< m),则模式串和文本串均要回退(i-1)位。KMP改进为:文本串不回退,模式串回退少于(i-1)位。即考虑模式串:当模式串s的s[1...k] = s[m-k+1...m],则用s的第(k+1)位和文本串的第(i+1)继续匹配。当文本串和模式串当前位(i+1)匹配失败时,确定模式串的下一比较位置依赖于t[i],t[i]为:既是s[i]的真后缀,又是s[i]前缀的子串的最大长度。即匹配失败时,从模式串的t[i]位的下一位开始和文本串的(i+1)位匹配。 分析:由于文本串不回退,复杂度即为o(n) 备注:回退:指从当前正在处理第x位,改为处理第y位,且y < x。 真后缀:ababac的真后缀可以是aba/abac等