KMP算法


一、KMP算法

KMP算法(The Knuth-Morris-Pratt Algorithm),即一种字符串匹配算法。
简单来说,普通的匹配步骤与KMP的差别:

普通匹配

  1. 从第一个模式串的字符开始匹配,比对主串的第一个字符
    1
  2. 如果第一个字符一样,则比对下一个字符,以此类推
    2
  3. 字符出现不匹配
    3
  4. 普通匹配(模式串与每个主串字符都尝试匹配一次):
    4
    KMP算法(以某种规律判定第2个字符肯定不符合,直接跳到对比第3个字符):
    5

二、算法PMT公式

对于上述的KMP匹配中的规律,即是PMT (部分匹配表 Partial Match Table) 计算出的Next数组,该数组表示下一个比较的主串字符移动的位置。
如何计算PMT?
6
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算法的内容,个人浅尝辄止,仅供参考。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值