我想实现 boyer-moore 算法,但我坚持构建一个我认为应该具有 O(n) 复杂度的好的后缀表,我只找到了 O(n^2) 算法。所以你们有我的线索吗?
请不要给我代码片段,如果我愿意,我可以谷歌它,但我更喜欢以我的方式解决它,我只需要一个线索。
我想实现 boyer-moore 算法,但我坚持构建一个我认为应该具有 O(n) 复杂度的好的后缀表,我只找到了 O(n^2) 算法。所以你们有我的线索吗?
请不要给我代码片段,如果我愿意,我可以谷歌它,但我更喜欢以我的方式解决它,我只需要一个线索。
有一种使用前缀函数的快速算法。字符串 s 的前缀函数是一个数组 p,其中 p[i] 是子字符串 s[0..i](0-indexed)及其后缀的前缀的最长长度。它可以使用使用 2 个事实的 KMP 以 O(n) 复杂度计算:
算法(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)。