【问题标题】:O(n) algorithm for constructing suffix table in boyer-moore string matching algorithmboyer-moore字符串匹配算法中后缀表的O(n)算法
【发布时间】:2013-10-05 06:37:14
【问题描述】:

我想实现 boyer-moore 算法,但我坚持构建一个我认为应该具有 O(n) 复杂度的好的后缀表,我只找到了 O(n^2) 算法。 那么你们对我有什么线索吗?

请不要给我代码sn-ps,如果我愿意我可以google它,但我更喜欢用我的方式解决它,我只需要一个线索。

【问题讨论】:

    标签: string algorithm boyer-moore


    【解决方案1】:

    有一种使用前缀函数的快速算法。 字符串 s 的前缀函数是数组 p,其中 p[i] 是子字符串 s[0..i](0-indexed)及其后缀的前缀的最长长度。 它可以使用使用 2 个事实的 KMP 以 O(n) 复杂度计算:

    1. p[i+1]
    2. 对于每个 i,如果 s[p[i]]==s[i+1],则 p[i+1] = p[i] + 1。否则,我们应该尝试另一个字符串,其中 s [0...j-1]==s[i-j+1...i]。显然,(我们选择最长的字符串)我们应该直接跳转到 i = p[i-1] 的位置。

    算法(c++):

    vector<int> prefix (string s) 
    {
        int n=s.length();
        vector<int> pi(n);
        pi[0]=0;
        for (int i=1; i<n; ++i) 
        {
            int j = pi[i-1];
            while (j>0 && s[i]!=s[j])
                j=pi[j-1];
            if (s[i]==s[j])  ++j;
            pi[i]=j;
        }
        return pi;
    }
    

    现在我们可以构造后缀表了:

    m = text.length();
    vector<int> suffshift(m);
    vector<int> pi = prefix(pattern);
    vector<int> pi1 = prefix(inverse(pattern));
    for (int j=0; j<m; ++j)
    {
        suffshift[j] = m - pi[m];
    }
    for (int i=1; i<m; ++i)
    {
         j = m - pi1[i];
         suffshift[j]=min(suffshift[j], i-pi1[i]);
    }
    

    Suffshift[m] 代表空后缀,suppshift[0] - 代表整个文本。复杂度为 O(n)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 2016-07-25
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多