Horspool字符串匹配算法

来源:互联网 发布:怎么在淘宝搜高仿lv 编辑:程序博客网 时间:2024/06/05 03:31

本文要在掌握了Kmp算法的基础上阅读比较妥当

Horspool和Kmp算法有点相识,都是采用空间换时间的想法,从而达到算法运算速率的提高,运算效率也都是θ(n),在最佳情况下,它的时间复杂度是O(n/m),


不过,Horspool也有自己的不同点:

1、每次匹配不正确时,移动的算法和Kmp不一样

2、采用模式从右到左的匹配,一旦匹配不正确,模式串相对文本串移动table[i]个字符


先看一下该算法执行的移动过程

字符cABCDEF...R...Z-移动距离42661663666



J I M _ S A W _ M E _  I N _  A _   B A R B E R S H O P

BAR B E R                  B A R B E R

                B A R B E R               B A R B E R

                     B A R B E R                  B A R B E R


              B  A  R B  E  R

table       2  4  3  2   1  3

接下类我们看一下他的移动数据数组是怎么求的

t(c) = {模式的长度m                                    如果c不包括在模式的前m-1个字符中)

           模式前m-1个字符中最右边的c到模式最后一个字符的距离                   (其他情况)


/** * 输入: 模式p[0..m-1]以及一个可能出现字符的字母表 输出: 以字母表中字符为索引的数组table[0..size-1] <br/> * 把模式串没有的字符table设为m,有的设为m-1-i,i以模式中当前字符位置最小值 *  * @param m *            模式串 * @return */public static int[] shiftTable(char m[]){int[] table = new int[255];int len = m.length;// 把模式串没有的字符table设为m,有的设为m-1-i,i以模式中当前字符位置最小值Arrays.fill(table, len);// 这里边界为len-1,len-1得为吗,如果位置为0时,死循环for (int i = 0; i < len - 1; i++){table[m[i]] = len - 1 - i;}return table;}


匹配过程

/** * 匹配过程 *  * @param m 模式串 * @param t 文本串 * @return */public static int horspoolMatching(char m[], char[] t){int[] table = shiftTable(m);int mLen = m.length;int tLen = t.length;// 当前匹配模式串位置,由末尾开始匹配int i = mLen;// 匹配模式字符串字符个数int k;while (i < tLen){k = 0;while (k < mLen && t[i - 1 - k] == m[mLen - 1 - k])k++;// 当匹配个数等于模式串个数if (k == mLen)return i - mLen;elsei += table[t[i - 1]];}return -1;}


测试程序

public static void main(String[] args){String mS = "abcbdc";String tS = "sdfabcdabcbdcsd";// 打印返回的下标值System.out.println(horspoolMatching(mS.toCharArray(), tS.toCharArray())); //输出7}


args[0]    BARBER 

args[1]    JIM_SAW_ME_IN_A_BARBERSHOP

输出:16