(未完)字符串模式匹配的几个方法
来源:互联网 发布:360沙盒软件 编辑:程序博客网 时间:2024/06/05 21:59
参考资料:
模式匹配的Brute-Force算法和KMP算法
Matrix67博客--KMP算法详解
一、Brute-Force算法
Brute-Force算法(BF,简单模式匹配算法)的基本思想就是:
- 从主串s=”S0S1…Sn-1”的第一个字符开始和模式串P=”P0P1…Pn-1”的第一个字符比较;
- 若相等,则继续比较后续字符;
- 若不等,从主串s的第二个字符开始重新与模式串t的第一个字符比较;
- 如此不断继续,若存在模式串中的每个字符依次和主串中的一个连续字符序列相等,则匹配成功,返回模式串 P 的第一个字符在主串中的下标;
- 否则匹配失败,返回-1。
范例如下:
算法效率:
易知BF算法的时间复杂度是O(m*n). 慢的原因主要是:记一次比较时目标串S开始的位置为K,然后模式串P在和目标串S匹配到中途失效的时候,模式串P需要重新指向串开始的位置,更严重的是目标串要回退到K+1的位置。----简而言之,就是虽然模式串和目标串中途匹配了很多字符,直到遇到某个字符失败,而在重新开始比较时,目标串比较的起始位置需要回退,回退后且只比前一次比较移动了一个位置。显然,中途匹配的都是无用功。假定目标串S不动,模式串P在平行于目标串移动,这次失败让模式串S相对于目标串P只向右移动了一个位置。
然后有时明明知道移动一个位置,也不可能产生正确的结果-----聪明的移动方法(KMP)是,匹配失效时,利用已知信息,让模式串S相对于主串P能有尽可能多的向右移动,或者是匹配失败时,主串指针尽可能少的回退。最坏的情况就是回退到上一次开始的位置的下一个(BF方法)。如下所示:
二、KMP算法
KMP算法(Knuth-Morris-Pratt) 就是前面所说的移动时的”聪明“方法,前提是要求一些已知信息 ---- 这就是KMP算法中最重要:对模式串P所构建的 Shift 表。 基本算法思想是:
- 设S为主串,P为模式串,设i 为主串S当前比较字符的下标,j 为模式串P当前比较字符的下标,另i和j的初值为0;
- 当Si= Pj时,i和j分别增1再继续比较;
- 否则i不变,j 改变为等于next [j] ,再继续比较。
- 依次类推,直到下列两种情况之一:一种是j退回到某个j = next[j] 时有si = tj;则i和j分别增1再继续比较;另一种是j退回到j = -1,此时令主串和模式串的下标各增1(此时模式串下标便退回0:j = j + 1 = -1 + 1 = 0),再继续比较。
KMP算法在Matrix67的博客中讲的非常详细,其博客中总结的一句话是:扫描主串S,并更新可以匹配到模式串P的什么位置 ----其伪代码中的字符串下标是从1开始计数
算法的关键:next[]数组的确定
这个过程就是前面说的,对模式串P所构建的 Shift 表,该过程只和模式串有关。因而可认为:KMP算法适用于,给定一个模式串P和一群不同的主串{S},问模式串P是哪些主串S的子串。
这个过程也可以理解为对模式串P的 自匹配过程。重要的思想就是:对模式串P的某个字符 j,找到其前面的字符串P1 P2...Pj-1中 Max { 缀长度 | 前缀==后缀} ,该值就是next[j]的值。具体可定义如下(模式串下标从0开始计算,t 即为P)
①next[j]= max{ k | 0<k<j 且“t0t1…tk-1” = “tj-ktj-k+1…tj-1”} 当此集合非空时
②next[j]= 0 其他情况
③next[j]= -1 当 j = 0 时
综上,KMP算法的过程分为两步:第一个是对模式串P做预处理,根据模式串本身的性质,从寻找前串中的最大 前缀==后缀长度,定义出next[] 数组;第二个是将模式串P和主串S去比较,当比较到模式串中某个字符j 和主串中字符i 不相等的时候,将j重新置为next[j],再和主串中的i比较 ----- 这样就保证了,主串指针i 没有回退的情况。
三、Boyer-Moore算法
BM算法也是适用于单模式快速匹配的方法,算法的性能是:
- BM算法比KMP算法要快;
- 当模式中重复的部分很好时,BM算法效率高(类似KMP)
- 需要比较的字符串数比输入字符串的长度(主串长度)n要小的多 --- KMP算法是主串每个字符都要比较
具体算法过程待补充
四、WM算法--适用于多模式匹配的算法
主要是涉及到了三个表--Shift表、Pointer表、Prefix表
具体算法待补充
- (未完)字符串模式匹配的几个方法
- 字符串的模式匹配方法
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 字符串的模式匹配
- 正则表达式(RegExp)的方法和字符串的模式匹配方法
- 字符串的模式匹配(回溯法)
- 字符串的模式匹配(BF、KMP)
- 关于字符串匹配(单模式匹配)的各种算法
- 字符串的模式匹配(朴素匹配、KMP)
- 几个高效的字符串匹配算法
- 字符串的简单模式匹配
- 简单的字符串模式匹配
- 回溯的字符串模式匹配
- Flex做成Map类型
- 高性能HTTP加速器Varnish-3.0.3搭建、配置及优化
- ios指南针小例子
- JQuery常用函数及功能小结
- upstart封装nodejs应用为系统服务
- (未完)字符串模式匹配的几个方法
- leetcode__Two Sum
- 二叉树层次遍历和深度遍历
- 所谓线程安全是指
- myeclipse jvm调整
- cocos2d-x 3.0 bata for android环境配置
- ActiveRecord中Find与Where区别
- 初入职场:你真的会写电子邮件吗
- IBM Java 7 新特性和在 WAS 8.5 中的配置