Horspool 字符串匹配算法

Horspool 字符串匹配算法对Boyer-Moore算法的简化算法。

Horspool 算法是一种基于后缀匹配的方法,是一种“跳跃式”匹配算法,具有sub-linear亚线性时间复杂度

Horspool 算法:

对于每个搜索窗口,该算法将窗口内的最后一个字符模式串中的最后一个字符进行比较。如果相等,则需要进行一个校验过程。该校验过程在搜索窗口中从后向前对文本和模式串进行比较,直到完全相等或者在某个字符处不匹配。无论匹配与否,都将根据字符d在模式串中的下一个出现位置将窗口向右移动

 可以使用下图进行理解:

(1)窗口大小与模式串大小相同,窗口内容为文本内容的一部分。

(2)对于窗口而言,每次从后向前匹配,直到全部相等(匹配),或者遇到不相等。

(3)遇到不相等时,根据窗口中最后一个字符在模式串中的位置,窗口进行移动。如果模式串中有多个相同的字符,选择最后一个字符为准,以避免漏解。

Horspool 字符串匹配算法

代码(C++):

#include<iostream>
#include<string>

using namespace std;

//计算可跳转字符个数数组
void getDis(string &str, int *dis) {
    int len = str.length();

    for (int i = 0; i < 256; ++i)
        dis[i] = len;//最大跳跃字符数
    
    for (int i = 0; i < len - 1; ++i)//注意这里不包括最后一个
        dis[str[i]] = len - i - 1;
}

//查找
void search(string &s, string &p, int dis[]) {
    int j;
    int pos;
    bool flag = false;
    int lenp = p.length();
    int lens = s.length();

    j = 0;
    pos = 0;
    while (pos <= lens - lenp) {
        j = lenp - 1;
        while (j >= 0 && p[j] == s[pos + j])//向前搜索匹配
            --j;
        if (j == -1) {
            flag = true;
            cout << "在模式串中第 " << pos + 1<< "号位" << endl;
            pos += lenp;
            continue;
        }
        else
            pos += dis[s[pos + lenp - 1]];//使用最后一个字符对齐的方法,进行“跳跃”移动
    }
    if(!flag)//不存在匹配
        cout << "-1" << endl << endl;
    cout << endl;
}

int main() {
    int dis[256];
    string s, p;
    while (1) {
        cout << "文本串: ";
        cin >> s;
        cout << "模式串:";
        cin >> p;
        getDis(p, dis);
        search(s, p, dis);
    }
    return 0;
}

Horspool 字符串匹配算法

相关推荐