Horspool 字符串快速查找算法
Horspool算法是后缀搜索算法,对于每个文本搜索窗口,将窗口内的最后一个字符与模式串(needle)的最后一个字符进行比较。如果相等,则继续从后向前验证其他字符,直到完全相等或者某个字符不匹配。当遇到字符不匹配的情况时就需要将搜索窗口往后移动,计算移动的距离可以有不同方法,Wikipedia中给出的C语言实现版本是基于窗口的最后一个字符(haystack上的)。
C语言版代码分析:
1 // 在 haystack 中查找 needle 子字符串 2 const unsigned char *horspool_memmem(const unsigned char *haystack, size_t hlen, 3 const unsigned char *needle, size_t nlen) 4 { 5 size_t scan = 0; 6 7 // 单个字符的位移对照表 8 size_t bad_char_skip[UCHAR_MAX + 1]; 9 10 // 参数检查 11 if (nlen <= 0 || !haystack || !needle) 12 return NULL; 13 14 // 初始化位移对照表,缺省值是 needle 的长度,即遇到不匹配时将搜索窗口往后移动 needle 长度 15 // 比如:如果遇到 needle 中没有的字符时,就可以将搜索窗口后移 needle 长度,以跳过该字符 16 for (scan = 0; scan <= UCHAR_MAX; scan = scan + 1) 17 bad_char_skip[scan] = nlen; 18 19 // needle 最后一个字符的下标 20 size_t last = nlen - 1; 21 22 // 遍历 needle 的字符(排除最后一个字符),计算该字符到最后一个字符的位移。 23 // 此处遍历需要从头开始,因为 needle 中可能会出现重复字符,同一个字符必须使用其最后出现位置的位移。 24 // 25 // 排除 needle 最后一个字符的原因是:如果 needle 的最后一个字符在 needle 中是唯一的,那么其位移对照表中的值是 nlen, 26 // 只要当次搜索匹配失败,并且搜索窗口上 haystack 的最后一个字符就是 needle 的最后一个字符,那么就应该将搜索窗口后移 nlen, 27 // 因为该字符没有重复出现 needle 的其它位置上,就可以安全的跳过当前窗口。 28 for (scan = 0; scan < last; scan = scan + 1) 29 bad_char_skip[needle[scan]] = last - scan; 30 31 // 开始搜索匹配 32 // 由于搜索窗口不断往后移动,即 haystack 指针值向后移动,hlen 保存 haystack 的剩余字符串长度。 33 // 当 hlen 的长度小于 nlen 时,查找失败。 34 while (hlen >= nlen) { 35 // 从搜索窗口的尾部向前匹配 36 for (scan = last; haystack[scan] == needle[scan]; scan = scan - 1) { 37 if (scan == 0) // 头部字符匹配则查找成功,返回子字符串位置 38 return haystack; 39 } 40 41 // 如果匹配失败则基于搜索窗口上 haystack 的最后一个字符 haystack[last] 后移搜索窗口 42 hlen -= bad_char_skip[haystack[last]]; 43 haystack += bad_char_skip[haystack[last]]; 44 } 45 46 // 到达此处说明查找失败 47 return NULL; 48 }
查找过程示例:
原始串 haystack: efaboxcbcabcdsdxzcxx needle: abcd初始化 last: 3 bad_char_skip['a'] = 3 bad_char_skip['b'] = 2 bad_char_skip['c'] = 1 bad_char_skip['d'] = 1循环1 last: 3 haystack[last]: b bad_char_skip[haystack[last]]: 2 haystack: aboxcbcabcdsdxzcxx needle: abcd循环2 last: 3 haystack[last]: x bad_char_skip[haystack[last]]: 4 haystack: cbcabcdsdxzcxx needle: abcd循环3 last: 3 haystack[last]: a bad_char_skip[haystack[last]]: 3 haystack: abcdsdxzcxx needle: abcd循环4 匹配成功
参考文档
- Boyer–Moore–Horspool algorithm - Wikipedia
- Horspool字符串匹配算法
转载于:https://www.cnblogs.com/edwardlost/archive/2013/01/25/2875320.html
Horspool 字符串快速查找算法相关推荐
- C++Rabin Karp算法字符串快速查找(附完整源码)
C++Rabin Karp算法字符串快速查找 C++Rabin Karp算法字符串快速查找完整源码(定义,实现,main函数测试) C++Rabin Karp算法字符串快速查找完整源码(定义,实现,m ...
- Rabin-Karp 算法(字符串快速查找)
Rabin-Karp 算法(字符串快速查找) 算法 代码 算法 Go 语言的 strings 包(strings.go)中用到了 Rabin-Karp 算法.Rabin-Karp 算法是基于这样的思路 ...
- java快速查找算法_Java实现的快速查找算法示例
本文实例讲述了Java实现的快速查找算法.分享给大家供大家参考,具体如下: 快速查找算法,可以根据想要找的是第几个大的数,每次循环都能固定下来一个数在数组完整排完序之后的位置,每次循环都能定一个数的位 ...
- python 查找算法_python快速查找算法应用实例
文实例讲述了Python快速查找算法的应用,分享给大家供大家参考. 具体实现方法如下: import random def partition(list_object,start,end): rand ...
- 采样点 求拐点 算法 c语言,平面曲线离散点集拐点的快速查找算法.pdf
平面曲线离散点集拐点的快速查找算法 第 25 卷 第 6 期 北 方 交 通 大 学 学 报 Vol . 25 No . 6 200 1 年 12 月 J OU RNAL OF NOR THERN J ...
- java 实现快速筛选_Java实现的快速查找算法示例
本文实例讲述了Java实现的快速查找算法.分享给大家供大家参考,具体如下: 快速查找算法,可以根据想要找的是第几个大的数,每次循环都能固定下来一个数在数组完整排完序之后的位置,每次循环都能定一个数的位 ...
- Tire树(字典树-字符串快速查找)
前言 一.Tire树是什么? 二.怎么建立tire树 1.字符串插入Tire树入 2.查找字符串 总结 前言: 最近是在复习基础算法,正好复习到了数据结构,所以写了自己对Tire树的理解,数据结构对我 ...
- java对字符串快查找_字符串快速查找 - Trie算法
Trie算法 先对给定的字符串进行归集,形成一个多叉树形结构. 使用字符导航方式作匹配查找. trie算法有很多变种,以最左(前缀)匹配为例进行说明. 优点 使用字符导航查找方式,能最大限度减少字符比 ...
- java字符串表表容量_java – 我可以使用什么符号表来存储~50 mil的字符串,快速查找而不会耗尽堆空间?...
我有一个约5000万字符串的文件,我需要在启动时添加到某种符号表中,然后以合理的速度搜索几次. 我尝试使用DLB trie,因为查找会相对较快,因为所有字符串都是< 10个字符,但在填充DLB时 ...
最新文章
- Entity Framework ModelFirst尝试
- Lambda-函数式接口(1)
- ubuntu系统中samba服务器搭建
- codeforces855 C. Helga Hufflepuff‘s Cup(树形dp)
- 正则表达式之 贪婪与非贪婪模式详解
- 使用AWS CloudWatch 调优Lambda函数 | 技术头条
- C语言的数据类型→浮点型数据
- 在春天,我用秋来诱惑你
- find和xargs
- 如何拒绝国外IP/屏蔽国外IP访问服务器?
- [2022年大学生创新创业训练计划项目立项申报]
- Linux本地信息收集
- qpython3.7.4版本下载_QPython3app下载
- 《当代教育心理学》(第2版)学习笔记
- 用python实现数度游戏
- python-scikit-learn基础
- 腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践
- 写完的文档有多少个字?字数统计在word哪里
- 重磅推荐,国内国外优秀的素材资源网站
- 做为站长眼光要放在远方