/* 快速字符串查找函数:
目前比较流行的字符串有KMP与BM算法,实际上KMP算法在使用的时候比strchr快不了多少,而BM算法也
大约只有KMP算法的3~5倍。这里介绍一个快速字符串查找函数。
举一个例子:
"Hello, world"中查找"word"子串,可以先把两个字符串按照首字节对好:
Hello, world
world
我们可以看出刚开始是不能匹配的,这样需要将子串往后移,至于每次移动多少就成了各种算法值得玩
味的地方了,当然,每次移动一个字符是最简单也最慢的算法;KMP利用以前匹配的信息进行移动,BM算
法利用反向查找的策略来加快移动。
我们可以知道,如果可以匹配的话,当前匹配的后一个字符","肯定需要判断,先检查","在子字符串中
不存在,所以直接移动子字符串的长度个位置,变成下面的模式:
Hello, world
world
继续看后面一个字符"d"在子字符串"world"中倒数第1个位置,将子字符串的"d"与查找字符串的"d"对齐
(移动1位),可以发现:
Hello, world
world
经过3次移动,便找到了查找子字符串,可以证明该方法平均移动的距离比BM算法大,所以该算法比BM算
法快。
*/
char *qsearch(char *text, int n, char *patt, int m)
{
int i = 0;
int tab_p[128] = {0};
char *p = patt;
char *temp_t, *t = text;
if (n < 0)
{
n = strlen(text);
}
if (m < 0)
{
m = strlen(patt);
}
if (m == 0)
{
return text;
}
/* 构造移动表,假设字符都在0~127之间,即纯ASCII码 */
for (i=0; i < 128; i++)
{
tab_p[i] = m + 1;
}
for (; *p; p++)
{
tab_p[*p] = m - (p - patt);
}
/* 开始移动查找 */
while (t+m <= text+n)
{
for(p = patt, temp_t = t; *p != 0; p++,temp_t++)
{
if (*p != *temp_t)
{
break;
}
}
if (*p == 0) /* 找到了 */
{
return t;
}
t += tab_p[*(t+m)];
}
return NULL;
}