BMH文本搜索算法

全称:Boyer-Moore-Horspool算法

实现从text中搜索pattern,返回其最小出现的位置;

算法思想:

1. 搜索文本时,从后到前搜索;

2. 如果碰到不匹配时,移动pattern,重新与text进行匹配;

关键:移动位置的计算shift_table如下图所示。

其中k为Pattern[0 ... m-2]中,使Pattern [ k ] ==Text [ i+m-1 ]的最大值;

                                                    如果没有可以匹配的字符,则使Pattern[ 0 ]==Text [  i+m ],即移动m个位置

3. 如果与Pattern完全匹配,返回在Text中对应的位置;

4. 如果搜索完Text仍然找不到完全匹配的位置,则返回-1,即查找失败

计算公式为:

如果在Pattern[0...m-2]中有Text[i+m-1]对应的字符c:shift[ (int)c ]=m-1-max{ 0 =< i < m-1 | p[i]=c }

如果在Pattern[0...m-2]中没有对应的字符c:shift[ (int)c ]=m

BMH文本搜索算法_第1张图片


有匹配时的图:

BMH文本搜索算法_第2张图片

性能分析:

Text对应长度为m,Pattern对应长度为n

时间复杂度:O(m*n);

空间复杂度:固定为256(ASCII中值的个数)

代码实现:

/*Data:2011.9.12  Middle Autumn Day*/
/*Authur: Bai YongHui*/
/*text: search in it; pattern: want to search*/
/*get the minial position whear pattern appears in text*/

#include <stdio.h>
#include <string.h>

//计算shift表
void getShiftTable(int table[], int num, char pattern[])
{
	int len=strlen(pattern);
	int nArrayIter=0;
	for(; nArrayIter<num; nArrayIter++)
		table[nArrayIter]=len;
	int nCharIter=0;
	//注意这样循环的好处在于:如果有重复的字符,左边赋的shift值会被右边的相同字符的shift覆盖掉
	//从而保证正确性
	//a[0...len-2]
	for(; nCharIter<len-1; nCharIter++)
		table[(int)pattern[nCharIter]]=len-1-nCharIter;
}

//BMH Search算法
int BMHSearch(char text[], char pattern[])
{
	int nTextLen=strlen(text);
	int nPatternLen=strlen(pattern);

	int shiftTable[256]={0};
	getShiftTable(shiftTable, 256, pattern);

	int nTextPos=0;
	int nPatternPos;

	//text[nTextPos+nPatternLen-1...0]
	while(nTextPos+nPatternLen<nTextLen)
	{
		//printf("%d\n", nTextPos);
		//每换到一个新的位置查找pattern,都需要重置nPatternPos
		nPatternPos=nPatternLen-1;
		//小循环,遍历pattern[nPatternLen-1...0]
		while(nPatternPos>=0)
		{
			if(pattern[nPatternPos]==text[nTextPos+nPatternPos])
			{
				nPatternPos--;
			}
			else
			{
				nTextPos+=shiftTable[(int)text[nTextPos+nPatternLen-1]];
				break;
			}
		}
		if(nPatternPos<0)
			return nTextPos;
	}
	//search failed
	return -1;
}

void main()
{
	char * text="detective";
	char * pattern="date";
	printf("%s\n%s\n", text, pattern);
	int firstPos=BMHSearch(text, pattern);
	if(firstPos==-1)
		printf("search failed\n");
	else
		printf("the first place where pattern appears is: %d\n", firstPos);
}

你可能感兴趣的:(c,算法,table,search,IM)