Horspool字符串匹配算法

本文要在掌握了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;
			else
				i += 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




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值