Horspool字符串匹配算法
来源:互联网 发布:历史地理 书籍 知乎 编辑:程序博客网 时间:2024/06/07 01:16
horspool算法为字符串匹配算法,比较的时候从模式的最右边开始和文本中的字符进行一一标胶,如果全部匹配成功就完成了,但是如果遇到不一样的,我们不会像蛮力法那样才移动一格,根据不同情况移动步子不同,有以下几种情况。(四种情况从算法课本里抄出来的,O(∩_∩)O哈哈~)
1:假设在文本中,对齐模式最后一个字符的元素是字符c,如果模式中不存在c(在我们的例子中,c就是字母S),模式安全移动的幅度就是他的全部长度
文本:A D C……………… S……………………
模式: B A R E B R
移动: B A R B E R
2:如果模式中存在c,但它不是模式的最好一个字符(在我们的例子中,c就是字母B),移动时应该把模式中最右边的c和文本中的c对齐:
文本:A D C……………… B……………………
模式: B A R E B R
移动: B A R B E R
3:如果c正好是模式中最后一个字符,但在模式中其他m-1个字符中不包含c,移动情况类似1,移动幅度为m
文本:A D C………… M B R……………………
模式: B A R E B R
移动: B A R B E R
文本:A D C……………… R……………………
模式: B A R E B R
移动: B A R B E R
所以说这个算法其实基本一直在判断模式的最后一个字母什么情况,我们可以建立一张表,比如这个模式遇见A的时候应该移动几部,遇见B的时候移动几步,还有空格,!,@#¥,等各种符号应该移动几步,很明显根据第一种情况就能猜到,比如模式是BAREBR,那说白了遇见除了BARE四个字母的其他全部字母,都应该移动6步,
我们只要把遇见BAER应该移动几步放入表中,其他元素均为6即可。
对于移动距离t(c)=模式的长度c(如果c不包含在模式的前m-1个字符中)
t(c)=模式前m-1个字符中最右边的c到模式最后一个字符的距离(其他情况下)
至于这个移动表怎么写,就是每个字母对应的移动步数,首先初始时所用元素对应的值都是模式长度m,然后对模式中的第j个字符(0<=J<=m-2),将它在表中应该移动步数改为m-1-j。还有一些细节没有说明,反正千言万语都在代码里了,代码注释我自己写的很多,本来还有很多细节想说出来的,但是语言表达能力不怎么好。先这样吧,等以后理解更加深刻了再来改改。
上边那个是表,就是每个字母应该移动多少步,下边是过程。
之后上代码,我在horspool类里写了相关的方法,主函数里调用了一下。
horspool类;
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Horspool算法{ class Horspool { /* 输入: 模式p[0..m-1]以及一个可能出现字符的字母表 * 输出: 以字母表中字符为索引的数组table[0..size-1] */ public int[] ShiftTable(char[] p, int m) { /*table是一个可能出现的字母表和它对应的应该移动步数,也就是某个字母应该 * 移动多少步这么一个表,但并不需要dictionary集合来完成,因为字符都是可以 * 转化为ASCALL码的,我们直接用每个不同的下标表示每个字母和符号即可,而值便是 * 应该移动的步数 */ int[] table = new int[127];//建立移动表 //首先移动将表中每个元素都置为m,m就是模式的长度 for (int i = 0; i < table.Length; i++) { table[i] = m; } /*移动表此时所以元素的值都是6,但是我们现在需要改变模式 * 中那几个字符对应的值,也就是说如果出现模式中的字符,我们 * 是不应该移动6格去的,而且模式中有可能出现相同字符的,比如 * BARBER,但是horspool算法是从模式右方进行匹配的,所以我们 * 赋值的时候应该从左往右去赋值,这样模式中字符对应的移动步数 * 的最后一次改写是在该字符最后一次出现的时候 */ for (int i = 0; i < m - 1; i++) { /*p []是char集合,p[i]对应是字母,循环的时候,比如模式 * 是BARBER,那么首先P[i]='B',table[B]=6-1-0=5,然后 * table[A]=6-1-1=4;table[R]=6-1-2=3;然后此时又是计算B了, * 这就是为什么我们这里要从左向右赋值的原因,这样B又被再次赋值, * 而此时的B是离右边最近的,table[B]=6-1-3=2,table[E]=6-1-4=1, */ table[p[i]] = m - 1 - i; //执行完后此时真正形成一个移动表,表中元素包含全部ACALL码对应的字符 //所应该移动的步长 } return table; } /*匹配过程*/ public int HorspoolMatching(char[] p, int m, char[] t, int n, int[] table) { int i = m - 1; //光标先定于模式最后一位 // 匹配模式字符串字符个数 int k = 0; while (i < n)//n是文本串的长度 { k = 0; /*K用来计量此时匹配了几个,K<m则表示此时还没有匹配完, * P[m-1-k]是模式中对应字符,t[i-k]是文本串中对应字符 * 如果相同则k++,继续对照前一个 */ while (k < m && p[m - 1 - k] == t[i - k]) k++; //当匹配个数等于模式串个数,返回下标 if (k == m) { return i - m + 1; } //否则移动对应的table移动表需要移动的距离 else i = i + table[t[i]]; } return -1; } }}program.cs:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Horspool算法{ class Program { static void Main(string[] args) { Horspool h = new Horspool(); // 取得模式串以及长度 char[] p = args[0].ToCharArray(); int m = p.Length; // 取得文本串以及长度 char[] t = args[1].ToCharArray(); int n = t.Length; int[] table = h.ShiftTable(p, p.Length); //找到返回的下标值 int index = h.HorspoolMatching(p, m, t, n, table); Console.WriteLine(index); ; Console.ReadKey(); } }}
好了就先这样了。
- Horspool字符串匹配算法
- Horspool字符串匹配算法
- Horspool字符串匹配算法
- HorsPool字符串匹配算法
- 字符串匹配算法horspool
- Horspool(字符串匹配)算法
- 字符串匹配之Horspool算法
- 字符串匹配之horspool算法
- 字符串匹配算法 之 (Horspool )Boyer-Moore-Horspool
- 【算法学习】horspool查找匹配字符串
- 字符串匹配 — Horspool
- 快速字符串模糊匹配--基于Horspool的模糊匹配算法
- 字符串匹配之horspool算法(简化的BM算法)
- sunday、kmp、 bm、 horspool字符串匹配算法 code
- 字符串匹配---KMP,Horspool,Boyer-Moore和Sunday等算法
- 字符串模式匹配之Brute force、KMP、Horspool算法
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
- 算法设计与分析基础-7.2、字符串匹配中的输入增强技术,Horspool算法
- ORACLE 日期和时间操作
- URI URL URN
- UMTS与WCDMA的关联分析
- 高效缓存Memcached 集成使用说明
- 大话设计模式
- Horspool字符串匹配算法
- 【tyvj1460】旅行
- [UBI]为AM335x uboot 移植UBI UBIFS功能
- Quartz CronTrigger最完整配置说明
- jQuery中$.fn的用法示例介绍
- java中wait,notify,notifyAll示例
- C++写动态网站之HelloWorld!
- CocoaPods安装和使用教程
- Web Service概念及用途