KMP算法
一、KMP算法
KMP算法(The Knuth-Morris-Pratt Algorithm),即一种字符串匹配算法。
简单来说,普通的匹配步骤与KMP的差别:
普通匹配
- 从第一个模式串的字符开始匹配,比对主串的第一个字符
- 如果第一个字符一样,则比对下一个字符,以此类推
- 字符出现不匹配
- 普通匹配(模式串与每个主串字符都尝试匹配一次):
KMP算法(以某种规律判定第2个字符肯定不符合,直接跳到对比第3个字符):
二、算法PMT公式
对于上述的KMP匹配中的规律,即是PMT (部分匹配表 Partial Match Table) 计算出的Next数组,该数组表示下一个比较的主串字符移动的位置。
如何计算PMT?
PMT的值是模式串的前缀集合与后缀集合的交集中最长元素的长度。
我们可以发现abad按照索引可以分为{a, ab, aba, abad}四个子串,其中前缀和后缀都不包含自身,即:
a 的前缀={null}, 后缀={null}, 无交集, PMT值=0;
ab 的前缀={a}, 后缀={b}, 无交集, PMT值=0;
aba 的前缀={a, ab}, 后缀={ba,a}, 交集={a}, PMT值=1;
abad的前缀={a, ab, aba}, 后缀={bad, ad, d}, 无交集, PMT值=0
因此 PMT={0, 0, 1, 0}.
索引通常是0开始,为了方便处理,在此右移一位使得PMT={-1, 0, 0, 1}.
简单的可以理解为:
三、 算法代码
//规律:
int[] GetNext(string strPattern)
{
int[] next = new int[strPattern.Length+1];//NEXT数组
int i = 0;//索引
int j = -1;//即使前缀索引又是匹配字符的数量
while(i<strPattern.Length)
{
if (j == -1 || strPattern[i] == strPattern[j])
{
i++;
j++;
next[i] = j;
}
else
j = next[j];
}
return next;
}
int KMP(string strMain, string strMatch,int[] next)
{
int i = 0;//strMain index
int j = 0;//strMatch index
while(i<strMain.Length && j < strMatch.Length)
{
if(j==-1 || strMain[i]== strMatch[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
//全长匹配
if (j == strMatch.Length)
return i - j;//最后匹配索引-长度=首位匹配索引
else
return -1;
}
四、 总结
以上是关于KMP算法的内容,个人浅尝辄止,仅供参考。
版权声明:本文为gehong3641原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。