Horspool和Sunday
目的:
以Horspool和Sunday算法为载体,试图在减少思维断层情况下学习作者算法思想
目录:
1:Horspool算法:简单的力量
2:Horspool代码实现
3:Sunday算法过程
4:Sunday代码实现
5:重新半理性审视BF、KMP、BM、Horspool和Sunday。(关键)
1:Horspool算法过程:简单的力量
Horspool算法的思路非常简单。它是对BM算法的一个简化。在BM中,作者使用了两种启发性规则即:坏字符规则和好后缀规则。Horspool认为,在某个字符匹配失败的情况下,挑选最后一个字符应用坏字符规则总是能够产生最大的跳跃距离。
过程阐述:
Horspool算法从右向左对字符匹配,如果最后一个字符相同,则匹配下一个字符,直到所有字符相同或者某一个字符不同;无论匹配成功与否,都根据最后一个字符进行在模式串中出现的位置进行移动。
如图:
所以Horspool算法只设计了一个shift算法来计算匹配失败的时候移动距离。
根据模式串,初始化一个数组。数组中保存的是该字符距离末位的距离。
之后从后向前开始匹配,匹配失败则从数组中取出对应移动距离
2:Horspool代码实现
public static int horspool(String target,String pattern){ //预处理 int skip []= precessChars(pattern); // int lengthMinusOne = pattern.length()-1; int i,j,k; for(k = lengthMinusOne;k<target.length();k+=skip[target.charAt(k)]){ //j>=0&&target.charAt(i)==pattern.charAt(j) 顺序不能改变 否则报数组越界 for(i=k,j=lengthMinusOne;j>=0&&target.charAt(i)==pattern.charAt(j);--j,--i){ //空 } if(j == -1){ return i+1; } } return -1; } private static int[] precessChars(String pattern){ final int count = 256; int [] skip = new int[count]; for(int j=0;j<count;j++){ skip[j] = pattern.length(); } //遍历到pattern.length()-1 不包含最后一个字符 for(int i =0;i<pattern.length()-1;i++){ char c = pattern.charAt(i); skip[c]=pattern.length()-1-i; } return skip; }
3:Sunday算法
其实Sunday算法也是BM算法的一个简化,和Horspool很是相像。差别在于当匹配失败的时候,Sunday算法选取的是最后一个字符的下一个字符进行匹配。但是Sunday算法并不要求匹配的时候从前到后或者是从后到前,甚至可以从中间开始匹配。
4:Sunday代码实现
//从后向前 public static int sunday_back(String target,String pattern){ //预处理 int skip []= precessChars(pattern); // int length = pattern.length(); int i,j,k; for(k = length;k<=target.length();k+=skip[target.charAt(k)]){ for(i=k-1,j=length-1;j>=0&&target.charAt(i)==pattern.charAt(j);--j,--i){ //空 } if(j == -1){ return i+1; } } return -1; } //从前向后 public static int sunday_forward(String target,String pattern){ //预处理 int skip []= precessChars(pattern); // int length = pattern.length(); int i,j,k; for(k = length;k<=target.length();k+=skip[target.charAt(k)]){ for(i=k-length,j=0;j<length&&target.charAt(i)==pattern.charAt(j);j++,i++){ //空 } if(j == length){ return k-length; } } return -1; } //预处理数组 private static int[] precessChars(String pattern){ final int count = 256; int [] skip = new int[count]; for(int j=0;j<count;j++){ skip[j] = pattern.length(); } //遍历到pattern.length()-1 不包含最后一个字符 for(int i =0;i<pattern.length()-1;i++){ char c = pattern.charAt(i); skip[c]=pattern.length()-i; } return skip; }
关于Sunday和Horspool算法,两者到底有多少差别,其实很难做出比较。一般来讲,Sunday算法能带来更大的平均移动距离。但是至于谁更快一些,可能涉及到内存引用次数等问题,需要大量的实验。
5:重新审视BF、KMP、BM、Horspool和Sunday。
当匹配失败的时候,到底怎么样才能跳跃式前进的距离最远呢?其实经过对Horspool和Sunday的分析,会得到一些启发。
Horspool中取当前字符中最后一个进行移位;Sunday算法选择最后一个字符的后一个进行移位。
启示1:既然Sunday选取最后一个的下一位,平均移位距离有所增加,何不选择最后一个的下两位呢?
启示2:何不综合Sunday和Horspool算法,将每次移位前取两者进行比较后更大者移动呢?
对于启示1,可以这样考虑,如果能够无限制的选取下一位,如果目标串中有个模式串中没有的字符X,岂不是就可以直接跳过X了?
对于启示2,实际上也是BF、KMP、和BM算法的差异所在之处。
通过上图比较,我们可以看出,如果综合Sunday算法和Horspool算法来考虑,效率不一定高,因为每次都将两者数组取出来的值比较一次,还不如就按照其中一个算法进行,这个时间内可能已经又向前迈进了一大步。
其实总和Sunday和Horspool的想法并没有错,我们最好的情况下就是将每个字符要移动的情况下都计算出来,取最大的(有点贪婪),但是就是在你根据不同字符计算需要移动的位置的时候,已经花费的大把大把的时间,可能Sunday算法已经执行完毕。所以我们要做的是在最少的时间内将获得的信息发挥最大的价值。
于是BF是怎么做的,简单的根据第一个字符进行移动;而KMP是根据已经匹配的字符的最大前缀(和该最大前缀相同的后缀是最靠近匹配失败的字符的)移动,如果符合KMP要求的后缀是多个字符,实际上相当于我们的启示2,比较了多个字符取其大,这个时候利用了预处理数组next,可以在o(1)时间内完成,是很有效果的。KMP实际可以稍微改动一下,并不利用已经匹配的字符,只是根据匹配失败的字符移动,相信效率会有所提升。再到后来的BM算法,终于发现了后缀匹配,但是BM算法还只是在利用坏字符规则的时候是根据匹配失败字符移动,好后缀规则实则起不到太大的作用,只是一个配角。然后Horspool彻底的摒弃了好后缀规则,就像我们曾经根据启示2试图总和Sunday和Horspool一样,Horspool没有这样做,而是选取了好后缀规则和坏字符规则中的一个即坏字符规则,这样做思路反而变得简单,收到的效果也还比BM好很多。而至于Sunday算法,做的更绝,直接选择最后一个字符的下一个字符,这个是能够选得最后一个字符了。用图片表示:
其实大量的信息都是在自己画的图上,能够半理性的展示这些算法的思想。
相关推荐
Boyer-Moore-Horspool-Sunday算法是字符串匹配领域中的一个高效算法,它结合了Boyer-Moore算法、Horspool算法以及Sunday算法的优点,以提高在文本中查找特定模式(子串)的速度。这个算法的主要目标是减少不必要的...
### 字符串匹配算法之Horspool算法:深入解析与应用 #### 引言 在计算机科学领域,字符串匹配是一项核心任务,广泛应用于文本编辑、数据检索、模式识别等多个场景。传统的简单匹配算法如逐一比较法往往在面对大...
算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 ...
C# 实现 Horspool 算法字符串匹配 Horspool 算法是一种高效的字符串匹配算法,用于查找目标字符串在源字符串中是否存在。该算法的核心思想是通过构建一个跳跃表,从而减少比较的次数,提高匹配效率。在本文中,我们...
Boyer–Moore–Horspool 算法的工作原理主要分为两部分:**预处理阶段**和**搜索阶段**。 ##### 1. 预处理阶段 预处理阶段主要用于构建一个或多个跳转表,这些跳转表用于指导搜索过程中如何快速移动匹配窗口。 - ...
实验的目的是通过编程实现和优化Horspool算法,以适应更广泛的输入数据类型和场景,提升算法的实用性和效率。 【知识点详解】: 1. **字符串匹配**:字符串匹配是指在一个文本串中查找一个模式串的过程。在文本...
在进行匹配时,Horspool算法首先将模式串和文本串的起始字符对齐,然后从模式串的最后一个字符开始,自右向左进行比较。如果比较失败,它会将模式串向后移动,而不是从头开始重新比较。 【模糊匹配】 模糊匹配是...
单模式匹配Horspool algorithm
### Horspool算法详解 #### 一、Horspool算法简介 Horspool算法是一种用于字符串搜索的高效算法,由Robert ...在实际开发中,Horspool算法可用于搜索引擎、文本处理工具等领域,能够有效地提升用户体验和程序性能。
用C++实现字符串模式匹配算法中的horspool算法
"Sunday算法特征码搜索极速定位基址和call地址C++(支持通配符)"这一主题涉及了程序逆向工程中的关键技术,主要是利用特定的算法来搜索内存中的特征码,以便快速找到代码的执行起点或者关键功能点,如函数调用地址...
接下来,我们将详细讨论C#中实现Horspool算法的关键步骤和原理。 Horspool算法的核心思想是通过预处理模式字符串(待查找的子串)来减少不必要的字符比较次数。预处理过程中,我们构建一个查找表,记录每个字符出现...
usage:四种字符串匹配算法的实现(Sunday、KMP、Boyer-Moore、horspool)的测试 各文件说明: search_string.h 头文件,包含了对各个函数的声明; search_string.c 包含了头文件中所有函数的具体实现; search_...
### 单字符串匹配算法总结 #### 一、引言 ...Horspool 算法和 Boyer-Moore 算法进一步引入了更加智能的移动策略,尤其是 Boyer-Moore 算法,在实践中表现卓越。选择合适的算法取决于具体的场景需求和性能要求。
本文改进了利用BM算法直接在LZ系列压缩文本上进行搜索的方案,主要是使用由BM算法衍生出的Sunday算法和Horspool算法。这些算法在匹配过程中,尽可能大距离地移动匹配窗口,忽略一些文本字符,从而加快匹配速度。 ...
在实验过程中,作者设计了一系列的实验来检验扩展后的Horspool算法在单字词、双字词和多字词的方块苗文字符串匹配中的性能。实验结果表明,该算法不仅能够保持线性查找过程,而且在不同的匹配场景下都展现出了较好的...
使Naive和Boyer Moore Horspool可视化,以帮助您了解这些算法的工作方式以及它们之间的比较方式。 目标 字符串匹配问题的目的是找到单词中所有出现的单词。 天真的算法 使用两个嵌套循环搜索文本。 外循环遍历所有...
字符串匹配是计算机科学中的一个重要问题,它广泛应用于文本编辑器、搜索引擎和生物信息学等领域。在众多字符串匹配算法中,Sunday算法是一种高效的模式匹配算法,它特别适合于对长文本串进行模式查找。Daniel M. ...
它结合了Boyer-Moore算法的好后缀规则和一个类似于Horspool算法的坏字符规则。Sunday算法通过对模式进行预处理生成一个跳跃表,从而在大多数情况下提供更快的查找速度。 此外,KMP(Knuth-Morris-Pratt)算法虽然...
在大量文本中查找特定模式串的问题,经典的KMP算法可以解决单个模式串匹配,但当面对多个模式串时,Boyer-Moore-Horspool、Sunday算法等多串匹配算法应运而生。这些算法利用模式串特性,减少了不必要的字符比较,...