`
十三月的
  • 浏览: 168827 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

打破思维断层之看穿Horspool和Sunday

阅读更多

 

HorspoolSunday

 

目的:

 

HorspoolSunday算法为载体,试图在减少思维断层情况下学习作者算法思想

 

目录:

 

1Horspool算法:简单的力量

 

2Horspool代码实现

 

3Sunday算法过程

 

4Sunday代码实现

 

5:重新半理性审视BFKMPBMHorspoolSunday。(关键)

 

 

 

1Horspool算法过程:简单的力量

 

         Horspool算法的思路非常简单。它是对BM算法的一个简化。在BM中,作者使用了两种启发性规则即:坏字符规则和好后缀规则。Horspool认为,在某个字符匹配失败的情况下,挑选最后一个字符应用坏字符规则总是能够产生最大的跳跃距离。

 

过程阐述:

 

Horspool算法从右向左对字符匹配,如果最后一个字符相同,则匹配下一个字符,直到所有字符相同或者某一个字符不同;无论匹配成功与否,都根据最后一个字符进行在模式串中出现的位置进行移动。

 

如图:



    
所以Horspool算法只设计了一个shift算法来计算匹配失败的时候移动距离。

 

根据模式串,初始化一个数组。数组中保存的是该字符距离末位的距离


 

 

 

 

 


    之后从后向前开始匹配,匹配失败则从数组中取出对应移动距离
 
2Horspool代码实现

 

 

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;
		
	}

 3Sunday算法

 

 

 

其实Sunday算法也是BM算法的一个简化,和Horspool很是相像。差别在于当匹配失败的时候,Sunday算法选取的是最后一个字符的下一个字符进行匹配。但是Sunday算法并不要求匹配的时候从前到后或者是从后到前,甚至可以从中间开始匹配。 

4Sunday代码实现

//从后向前
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;
		
	}

       关于SundayHorspool算法,两者到底有多少差别,其实很难做出比较。一般来讲,Sunday算法能带来更大的平均移动距离。但是至于谁更快一些,可能涉及到内存引用次数等问题,需要大量的实验。 

 

 

5:重新审视BFKMPBMHorspoolSunday

 

 

     匹配失败的时候,到底怎么样才能跳跃式前进的距离最远呢?其实经过对HorspoolSunday的分析,会得到一些启发。

         Horspool中取当前字符中最后一个进行移位;Sunday算法选择最后一个字符的后一个进行移位。

         启示1:既然Sunday选取最后一个的下一位,平均移位距离有所增加,何不选择最后一个的下两位呢?

         启示2:何不综合SundayHorspool算法,将每次移位前取两者进行比较后更大者移动呢?

 

 

     对于启示1,可以这样考虑,如果能够无限制的选取下一位,如果目标串中有个模式串中没有的字符X,岂不是就可以直接跳过X了?



 

 

 

 

 

对于启示2,实际上也是BFKMP、和BM算法的差异所在之处。



   
通过上图比较,我们可以看出,如果综合Sunday算法和Horspool算法来考虑,效率不一定高,因为每次都将两者数组取出来的值比较一次,还不如就按照其中一个算法进行,这个时间内可能已经又向前迈进了一大步。

       其实总和SundayHorspool的想法并没有错,我们最好的情况下就是将每个字符要移动的情况下都计算出来,取最大的(有点贪婪),但是就是在你根据不同字符计算需要移动的位置的时候,已经花费的大把大把的时间,可能Sunday算法已经执行完毕。所以我们要做的是在最少的时间内将获得的信息发挥最大的价值。

 于是BF是怎么做的,简单的根据第一个字符进行移动;而KMP是根据已经匹配的字符的最大前缀(和该最大前缀相同的后缀是最靠近匹配失败的字符的)移动,如果符合KMP要求的后缀是多个字符,实际上相当于我们的启示2,比较了多个字符取其大,这个时候利用了预处理数组next,可以在o1)时间内完成,是很有效果的。KMP实际可以稍微改动一下,并不利用已经匹配的字符,只是根据匹配失败的字符移动,相信效率会有所提升。再到后来的BM算法,终于发现了后缀匹配,但是BM算法还只是在利用坏字符规则的时候是根据匹配失败字符移动,好后缀规则实则起不到太大的作用,只是一个配角。然后Horspool彻底的摒弃了好后缀规则,就像我们曾经根据启示2试图总和SundayHorspool一样,Horspool没有这样做,而是选取了好后缀规则和坏字符规则中的一个即坏字符规则,这样做思路反而变得简单,收到的效果也还比BM好很多。而至于Sunday算法,做的更绝,直接选择最后一个字符的下一个字符,这个是能够选得最后一个字符了。用图片表示:



 其实大量的信息都是在自己画的图上,能够半理性的展示这些算法的思想。

 

 

 

 

  • 大小: 11 KB
  • 大小: 2.6 KB
  • 大小: 16.7 KB
  • 大小: 24.4 KB
  • 大小: 11.2 KB
  • 大小: 175.9 KB
  • 大小: 32.8 KB
5
6
分享到:
评论

相关推荐

    Boyer-Moore-Horspool-Sunday.rar_Boyer Moore_horspo_horspool_sund

    Boyer-Moore-Horspool-Sunday算法是字符串匹配领域中的一个高效算法,它结合了Boyer-Moore算法、Horspool算法以及Sunday算法的优点,以提高在文本中查找特定模式(子串)的速度。这个算法的主要目标是减少不必要的...

    字符串匹配算法之Horspool算法

    ### 字符串匹配算法之Horspool算法:深入解析与应用 #### 引言 在计算机科学领域,字符串匹配是一项核心任务,广泛应用于文本编辑、数据检索、模式识别等多个场景。传统的简单匹配算法如逐一比较法往往在面对大...

    算法设计 horspool算法 最优 最差输入

    算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 最优 最差输入算法设计 horspool算法 ...

    c# 实现Horspool

    C# 实现 Horspool 算法字符串匹配 Horspool 算法是一种高效的字符串匹配算法,用于查找目标字符串在源字符串中是否存在。该算法的核心思想是通过构建一个跳跃表,从而减少比较的次数,提高匹配效率。在本文中,我们...

    Boyer–Moore–Horspool algorithm

    Boyer–Moore–Horspool 算法的工作原理主要分为两部分:**预处理阶段**和**搜索阶段**。 ##### 1. 预处理阶段 预处理阶段主要用于构建一个或多个跳转表,这些跳转表用于指导搜索过程中如何快速移动匹配窗口。 - ...

    Horspool字符串匹配输入增强技术

    实验的目的是通过编程实现和优化Horspool算法,以适应更广泛的输入数据类型和场景,提升算法的实用性和效率。 【知识点详解】: 1. **字符串匹配**:字符串匹配是指在一个文本串中查找一个模式串的过程。在文本...

    基于Horspool算法的模糊匹配.pdf

    在进行匹配时,Horspool算法首先将模式串和文本串的起始字符对齐,然后从模式串的最后一个字符开始,自右向左进行比较。如果比较失败,它会将模式串向后移动,而不是从头开始重新比较。 【模糊匹配】 模糊匹配是...

    Horspool algorithm

    单模式匹配Horspool algorithm

    Horspool算法

    ### Horspool算法详解 #### 一、Horspool算法简介 Horspool算法是一种用于字符串搜索的高效算法,由Robert ...在实际开发中,Horspool算法可用于搜索引擎、文本处理工具等领域,能够有效地提升用户体验和程序性能。

    horspool.cpp

    用C++实现字符串模式匹配算法中的horspool算法

    Sunday算法特征码搜索极速定位基址和call地址C++(支持通配符)

    "Sunday算法特征码搜索极速定位基址和call地址C++(支持通配符)"这一主题涉及了程序逆向工程中的关键技术,主要是利用特定的算法来搜索内存中的特征码,以便快速找到代码的执行起点或者关键功能点,如函数调用地址...

    C#实现horspool匹配算法

    接下来,我们将详细讨论C#中实现Horspool算法的关键步骤和原理。 Horspool算法的核心思想是通过预处理模式字符串(待查找的子串)来减少不必要的字符比较次数。预处理过程中,我们构建一个查找表,记录每个字符出现...

    string_match:实现并对比了各类字符串匹配算法,包括Sunday、KMP、Boyer-Moore、horspool

    usage:四种字符串匹配算法的实现(Sunday、KMP、Boyer-Moore、horspool)的测试 各文件说明: search_string.h 头文件,包含了对各个函数的声明; search_string.c 包含了头文件中所有函数的具体实现; search_...

    单字符串匹配算法总结,有好几种方法的说明

    ### 单字符串匹配算法总结 #### 一、引言 ...Horspool 算法和 Boyer-Moore 算法进一步引入了更加智能的移动策略,尤其是 Boyer-Moore 算法,在实践中表现卓越。选择合适的算法取决于具体的场景需求和性能要求。

    大数据-算法-改进的LZ系列压缩文本上的搜索算法.pdf

    本文改进了利用BM算法直接在LZ系列压缩文本上进行搜索的方案,主要是使用由BM算法衍生出的Sunday算法和Horspool算法。这些算法在匹配过程中,尽可能大距离地移动匹配窗口,忽略一些文本字符,从而加快匹配速度。 ...

    Horspool扩展算法及其在方块苗文模式匹配中的应用

    在实验过程中,作者设计了一系列的实验来检验扩展后的Horspool算法在单字词、双字词和多字词的方块苗文字符串匹配中的性能。实验结果表明,该算法不仅能够保持线性查找过程,而且在不同的匹配场景下都展现出了较好的...

    stringmatching:字符串匹配算法:Naive和Boyer Moore Horspool Visualizer

    使Naive和Boyer Moore Horspool可视化,以帮助您了解这些算法的工作方式以及它们之间的比较方式。 目标 字符串匹配问题的目的是找到单词中所有出现的单词。 天真的算法 使用两个嵌套循环搜索文本。 外循环遍历所有...

    PHP实现的字符串匹配算法示例【sunday算法】

    字符串匹配是计算机科学中的一个重要问题,它广泛应用于文本编辑器、搜索引擎和生物信息学等领域。在众多字符串匹配算法中,Sunday算法是一种高效的模式匹配算法,它特别适合于对长文本串进行模式查找。Daniel M. ...

    比Boyer-Moore更快的字符串查找算法.rar_Boyer Moore_字符串查找_查找算法

    它结合了Boyer-Moore算法的好后缀规则和一个类似于Horspool算法的坏字符规则。Sunday算法通过对模式进行预处理生成一个跳跃表,从而在大多数情况下提供更快的查找速度。 此外,KMP(Knuth-Morris-Pratt)算法虽然...

    树状数组 后缀数组 字典树 多串匹配算法及启示

    在大量文本中查找特定模式串的问题,经典的KMP算法可以解决单个模式串匹配,但当面对多个模式串时,Boyer-Moore-Horspool、Sunday算法等多串匹配算法应运而生。这些算法利用模式串特性,减少了不必要的字符比较,...

Global site tag (gtag.js) - Google Analytics