学点字符串匹配——zbox
先来规定一些符号,S表示一个字符串,|S|表示字符串的长度,没有特殊说明n表示匹配串的长度,m表示模式串的长度。prefix(i)表示S的后缀S[i...n]。
zbox算法只是对一个字符串S求出一个数组Zbox[]。Zbox[i]表示的是prefix[i]和字符串S的最长公共前缀的长度。即zbox算法的目的是初始化所有字符串后缀对与原串的最长公共前缀长度。
先来看看通过Zbox[]数组如何进行精确匹配。匹配串记为S,模式串记为P。要用一个数组把S和P关联起来,一个常用的方法是把S和P连接。这里把P放在前面得到新串T = P+S。现在对新串进行zbox的过程求出Zbox[]。根据定义可知S串如果从i处匹配上了P串,则Zbox[i + m] = m。于是可以遍历T串的[m, n + m - 1],寻找匹配结果。
zbox的快速求Zbox[]的方法是在暴力的基础上对于可以确认的以前匹配过的字符直接跳过。算法的关键在于在比较中不断更新区间[l,r](zBox[l] = r - l + 1,这是通过计算prefix(l)更新的),使以后要计算的zBox[i]尽可能在[l, r]内。
现在考虑怎么通过[l, r]降低复杂度:
- T[l, r] = T[0, r - l + 1];
- i在[l, r]间;
- 由1,2:T[i, r] = t[i - l. r - l + 1];
- 由3:
- zBox[i] = zBox[i - l], 当i+zBox[i - l] < r, 因为i+zBox[i - l] + 1不会再匹配了
- zBox[i] = r - l + 1 + 暴力向后比较得到的值, 当i+zBox[i - l] >= r, 因为只能保证T[i, r] = t[i - l. r - l + 1],后面只能暴力计算不能根据prefix(i - l)(都不相等了)
上代码~
1 unsigned int * zbox(char * str) 2 { 3 int idx = 0; 4 int len = strlen(str); 5 unsigned int *zBox = (unsigned int *)malloc(len * sizeof(unsigned int)); 6 int l = 0, r = 0; 7 8 if(zBox == NULL) return NULL; 9 10 zBox[0] = len; 11 for(idx = 1; idx < len; ++idx) 12 { //这里的l必然小于idx,因为l总是等于之前的idx 13 if(idx > r)//现在正在计算的后缀不在已匹配字符段内,必须从头开始比较 14 { 15 l = r = idx; 16 while(r < len && str[r - l] == str[r]) ++r; 17 zBox[idx] = r - l, --r; 18 } 19 else //现在正在计算的后缀在已匹配字符段内,可以跳过某些字符 20 { 21 //这里还分两种情况,超界和未超界 22 int k = idx - l; 23 if(zBox[k] < r - idx + 1) zBox[idx] = zBox[k]; //未超界,当前最大ZBOX值求出,直接赋值 24 else 25 { 26 //超界,需要跳过一些字符继续比较。 27 l = idx; 28 while(r < len && str[r - l] == str[r]) ++r; 29 zBox[idx] = r - l, --r; 30 } 31 } 32 } 33 return zBox; 34 }
从这个代码可以看出r是递增不减的且r最大值是n - 1。所以均摊到外层每个循环里,while循环平均进行了1次,因此zbox复杂度为O(n)。
转载于:https://www.cnblogs.com/ACystalMoon/archive/2012/12/31/2840892.html
学点字符串匹配——zbox相关推荐
- 大量的数据做字符串匹配_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法...
前言 文章的一开头,还是要强调下字符串匹配的思路 将模式串和主串进行比较 从前往后比较 从后往前比较 2. 匹配时,比较主串和模式串的下一个位置 3. 失配时, 在模式串中寻找一个合适的位置 如果找到 ...
- 算法之路,带你轻松学废算法系列之字符串匹配(中)
文章目录 字符串匹配中 前言 KMP算法 KMP算法的基本原理 失效函数计算方法 问题解答 KMP 算法复杂度分析 小结 Trie树 什么是Trie树 如何实现一棵 Trie 树? Trie树的构造 ...
- 算法之路,带你轻松学废算法系列之字符串匹配(下)
文章目录 字符串匹配下 前言 引入 多模式串匹配算法:AC 自动机 AC自动机过滤敏感词 时间复杂度分析 小结 结尾 字符串匹配下 前言 大家好,我是魏果果哦,算法呢,是我们程序员一生无法避免的垫脚石 ...
- 零零散散学算法之再叙字符串匹配
出自:http://blog.csdn.net/fengchaokobe/article/details/8919074 字符串匹配问题这是个老话题了,而我们也热衷于学习和探讨这个问题,并且我们也经常 ...
- javascript 学习并梳理正则表达式姿势之字符串匹配( 一)
正则表达式字符串匹配相关 引:<JavaScript 正则表达式迷你书> 读老姚丨洞见生产者的<JavaScript 正则表达式迷你书>全是干货好书,通俗易懂,图文结合 正则是 ...
- CCF - 201409-3 - 字符串匹配
问题描述 试题编号: 201409-3 试题名称: 字符串匹配 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你 ...
- 字符串匹配shiftand算法
令人惊叹的Shift-And/Shift-Or 写在前面:Shift-And/Shift-Or是如此令人惊叹的算法,在KMP基础上开始一段神奇之旅. 目的:以Shift-And算法为载体,试图在减少思 ...
- 字符串匹配数据结构 --Trie树 高效实现搜索词提示 / IDE自动补全
文章目录 1. 算法背景 2. Trie 树实现原理 2.1 Trie 树的构建 2.2 Trie树的查找 2.3 Trie树的遍历 2.4 Trie树的时间/空间复杂度 2.5 Trie 树 Vs ...
- 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FFT)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 2021年度训练联盟热身训练赛第四场 H - Rock Paper Scissors(字符串匹配,FF ...
- Rabin-Karp ( 字符串匹配 )详解
字符串匹配,例从 字符串S 中( 长度为 n ),找到 字符串T ( 长度为 m ) 经典思路:遍历 字符串 S,对于每个都为起点,匹配一次,则 O( n m )的复杂度 但是这样我们就对 字符 重复 ...
最新文章
- Chapter 3、Java语法基础(二)----Java基本数据类型、变量与常量 (20th,Feb)
- (学习笔记)Jupyter notebook入门
- python3在线-荐python3在线编程输入输出总结
- JQuery中ajax方法访问web服务
- BAPI_PO_CREATE1
- typora高级设置字体_Mint(Linux)系统设置优化及其常用软件安装笔记
- python面向对象编程(封装与继承)
- 虚实结合:无需人工标注的可泛化行人再辨识
- 内核网络设备的注册与初始化
- 《InsideUE4》GamePlay 架构(二)Level 和 World
- 代码从GCC到MSVC的移植
- 怎样在Xcode 4下编译发布与提交App到AppStore?(转)
- InnoDB与Myisam的六大区别
- 一起谈.NET技术,HTML5 - 搭建移动Web应用
- 图片压缩大小的3种方法,简单快捷实用!
- 华为存储更换故障硬盘
- 大数据平台_大数据应用场景有哪些
- Word 2007 删除页眉横线
- archlinux + dwm系统美化
- easyui的filebox赋值回显
热门文章
- C语言题目:5-6 购物(一) (25 分)
- 实战案例!使用 Python 进行 RFM 客户价值分析!
- php域名重定向跳转,301域名重定向跳转设置(所有方法都在这)
- python 元类理解
- Unity 反转法线,在 Hierarchy 视图对象的快捷菜单中增加 Flip Mesh Normals(反转网格法线)项...
- 泛零售数据中台建设之灵魂问答 | 奇点云CEO行在直播回顾
- 基金暴跌年轻人为什么躲不过被割?
- php ffmpeg扩展下载
- 图像处理基本方法-perl语言生成纯色BMP文件
- 用js计时器写倒计时