字符串匹配算法
2021-05-05 13:30
标签:暴力求解 字符 特点 初始化 串匹配 基于 时间 next数组 ima 一. 简单的直接算法 比较次数:(n-m-1)*m次 时间复杂度O(mn) 二. Rabin-karp算法 (1)直接数值比较 b. 计算次数:1 + n-m 次 (2)hash函数数值比较 预处理:fp = p[ m-1 ] + 10*(p[ m-2 ] + …+ 10*(p[ 1 ] + 10*p[ 0 ] ))) mod q。 移位重新计算: 三.BM算法 1. 算法思想: (1)从后往前匹配的好处:在比较过程中不匹配的概率远远大于匹配的概率,基于这一特点,在匹配失败时,从后往前匹配的跳跃位置更大 (2)每次发生不匹配,根据好后缀规则和坏字符规则(规则都是对模式串而言的)跳转到下一次比较的位置 2. 算法设计 (1)预处理:(对模式串T进行预处理)P[ 0-n ] 坏字符规则:后移位数 = 失配位置 - 模式串上一次出现坏字符的位置(未出现记为 -1) 好后缀规则:后移位数 = 好后缀的位置 - 模式串上一次出现好后缀的位置(未出现记为 -1) (2)从左到右移动,从后往前比较,失配时移动位置 = max{ 坏字符规则 , 好后缀规则} 四. BMH算法 1. 算法思想: 总体上是BM算法的改进,关注点在模式串的最后一个字符,规则更简单 2. 算法设计 (1)预处理(对字符集/文本串预处理) 偏移表:P[ 0-m-1 ] (2)从左到右移动,从后往前比较 五. KMP算法---最坏情况依旧是线性 1. 算法思想: 文本中的每个字符仅匹配一次,充分利用已经匹配的部分做跳转 2. 算法设计 (1)计算最长公共前后缀:maxL 关于如何计算最长公共前后缀(例如P=abaabcac): A.暴力算法: 得到所有前缀和后缀,分别比较。 B. 递推算法: 得到P的所有前缀,第一个前缀的maxL初始化为0。 假设已经求得第 i 个前缀的maxLi = k , 求解第 i + 1 个前缀的maxL(i+1) 若 P[ k ] == P[ i ],maxL(i+1)= k+1; 否则,使用暴力算法计算maxL. 例: a 0 ab 0 递推 aba 1 递推 abaa 1 递推 abaab 2 递推(举例1) abaabc 0 暴力(举例2) abaabca 1 递推 abaabcac 0 暴力 maxL = { 0、0、1、1、2、0、1、0} (举例1)第四前缀abaa:maxL = 1,又P[ 1 ]==P[ 4 ] == b,则第五前缀abaab:maxL = 2 (举例2)此时不满足P[ k ] == P[ i ],暴力求解, 得到abaabc的所有前缀和所有后缀,对应比较 abaabcabaabc a c 0 ab bc 0 aba abc 0 abaa aabc 0 abaab baabc 0 则第六前缀abaabc:maxL = 0 (2).将maxlL整体右移一位,初始为 -1,得到next数组 next = { -1、0、0、1、1、2、0、1} (3)从左到右,从前往后匹配,失配时,将 next数组对应的值作为下标与失配位置对齐(j = next[ j ]) 字符串匹配算法 标签:暴力求解 字符 特点 初始化 串匹配 基于 时间 next数组 ima 原文地址:https://www.cnblogs.com/duanshuai/p/13192219.html
上一篇:java中如重复提供日期