最长前缀匹配(LPM)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最长前缀匹配(LPM)相关的知识,希望对你有一定的参考价值。
参考技术A最长前缀匹配 是指在IP协议中,被路由器用于在路由表中进行选择的一个算法。
因为路由表中的每个表项都指定了一个网络,所以一个目的地址可能与多个表项匹配。最明确的一个表项——即子网掩码最长的一个——就叫做最长前缀匹配。之所以这样称呼它,是因为这个表项也是路由表中,与目的地址的高位匹配得最多的表项。
字符串匹配:计算kmp算法中最长的前缀后缀数组
【中文标题】字符串匹配:计算kmp算法中最长的前缀后缀数组【英文标题】:String Matching: Computing the longest prefix suffix array in kmp algorithm 【发布时间】:2014-05-02 04:33:02 【问题描述】:KMP algorithm for string matching。 以下是我在网上找到的用于计算最长前缀-后缀数组的code: 定义:
lps[i] = the longest proper prefix of pat[0..i]
which is also a suffix of pat[0..i].
代码:
void computeLPSArray(char *pat, int M, int *lps)
int len = 0; // length of the previous longest prefix suffix
int i;
lps[0] = 0; // lps[0] is always 0
i = 1;
// the loop calculates lps[i] for i = 1 to M-1
while(i < M)
if(pat[i] == pat[len])
len++;
lps[i] = len;
i++;
else // (pat[i] != pat[len])
if( len != 0 )
// This is tricky. Consider the example AAACAAAA and i = 7.
len = lps[len-1]; //*****************
// Also, note that we do not increment i here
else // if (len == 0)
lps[i] = 0;
i++;
我可以用len = len-1
代替len = lps[len-1]
吗?
因为 len 总是从 [0 .. someIndex] 开始计算前缀长度。那为什么在这里使用 lps 进行赋值呢?以下是我测试过哪些工作正常的案例(第一行是模式,随后两行是原始分配和修改后分配给 len
的结果):
a a a b a b c
0 1 2 0 1 0 0
0 1 2 0 1 0 0
a b c b a b c
0 0 0 0 1 2 3
0 0 0 0 1 2 3
a a b c b a b
0 1 0 0 0 1 0
0 1 0 0 0 1 0
在此处编写两种变体的代码:http://ideone.com/qiSrUo
【问题讨论】:
【参考方案1】:在它不起作用的情况下:
i 0 1 2 3 4 5
p A B A B B A
c1 0 0 1 2 0 1
c2 0 0 1 2 2 3
原因是:
At i=4, len=2
p[i]='B' and p[len]='A' //Mismatch!
lps string upto i=3: AB(0-1 prefix), (2-3 suffix)
-------------------------------
i=4
Next charecter: B
len=2 // longest prefix suffix length
Charecter looking for : A (=p[len])
所以在 i=3 之前,我们将 AB(0-1) 作为与后缀 AB(2-3) 匹配的前缀,但现在在 i=4 处存在不匹配,所以我们看到我们可以' t 扩展原始前缀(0-1),因此要检查的位置是在“AB”之前找到的前缀,这是由 lps[len-1] 开始并且这不一定是 len-1,因为我们可能需要退后一步才能获得新的最长前缀后缀。
【讨论】:
【参考方案2】:这是我见过的最好的解释。其中的示例将清楚地回答您的问题。
Knuth–Morris–Pratt(KMP) Pattern Matching(Substring search)
【讨论】:
【参考方案3】:这是我的 KMP 代码:-
#include <bits/stdc++.h>
using namespace std;
int main(void)
int t;
scanf("%d",&t);
while(t--)
string s;
cin>>s;
int n = s.length();
int arr[n];
arr[0] = 0;
int len = 0;
for(int i = 1;i<n;)
if(s[len]==s[i])
len++;
arr[i++] = len;
else
if(len!=0)
len = arr[len-1];
else
arr[i] = 0;
i++;
cout<<arr[n-1]<<endl;
return 0;
时间复杂度为 O(N)
【讨论】:
【参考方案4】:如果您也想了解该算法背后的直觉,请参阅 YouTube 上的以下视频。这是我对这个算法遇到的最清楚的解释。
The longest prefix suffix array in kmp algorithm
【讨论】:
以上是关于最长前缀匹配(LPM)的主要内容,如果未能解决你的问题,请参考以下文章