子串查找的算法-----BM

字符串的匹配有著名的KMP之外還有另外一個算法,Boyer-Moore算法
下面是根據一篇文章學習來寫出的BM算法的代碼.算是學習下.
附上學習文章的鏈接http://blog.jobbole.com/104854/

#include<iostream>
#include<string>
#include<unordered_map>
#include<vector>

using namespace std;


int BM(const string &str, const string &substr)
{
    unordered_map<char,int> delta;//存放str中的字符最後一次出現的位置
    unordered_map<char, int> right;//用來存放子串中每個字符最右邊的距離

    unsigned sublen = substr.size();
    unsigned len = str.size();
    for (int i = len - 1; i >= 0; --i)
    {
        right[str[i]] = -1;
        delta[str[i]] = -1;
    }
    for (int i =sublen - 1; i >= 0; --i)
    {
        if (right[substr[i]] == -1)
        {
            right[substr[i]] = i;
        }
    }

    for (unsigned i = 0,skip = 0; i < len-sublen; i+=skip)
    {
        int j = sublen - 1;
        delta[str[i+j]] = j;
        for (; j >= 0; --j)
        {
            if (substr[j] != str[i + j])
            {
                skip =j - right[str[i + j]];
                skip2 = j-delta[str[i+j]];
                skip = skip < skip2 ? skip2 :skip;//取二者的最大值
                if (skip < 1)
                {
                    skip = 1;
                }
                break;
            }
        }
        if (j + 1 == 0)
        {
             //當需要統計一共有多少個子串時,需要清空delta並重新初始化.然後在繼續循環
            return i;//這裏就是找到了子串,函數的出口...
        }
    }

    return -1;
}

int main()
{
    string str;
    string substr;
    cin >> str >> substr;
    cout<<BM(str,substr);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章