zoukankan      html  css  js  c++  java
  • KMP字符串匹配算法

    1. KMP算法用途

    KMP算法用于解决主字符串和模式字符串匹配的问题。如果完成匹配,返回模式字符串在主字符串匹配的初始索引。如果不匹配,返回-1。

    2. PMT(Partial Match Table):部分匹配表(模式字符串)

    部分匹配表是KMP算法的核心,定义:前缀集合和后缀集合交集中最长元素的长度。

    前缀集合:如果字符串M = A + S,A和S非空,则A是M的一个前缀,所有的前缀组成前缀集合。

    后缀集合:如果字符串M = A + S,A和S非空,则S是M的一个后缀,所有的后缀组成后缀集合。

    图中表示了Index = 10时,PMT = 4的计算过程,前缀字符串abab与后缀字符串abab匹配。

    3. KMP算法实现

    如果主字符串是T,匹配字符串是P,T[ i ] != P[ j ]时,此时可以通过右移匹配字符串PMT[ j - 1 ]个单位来解决,即令 j = PMT[ j - 1]

    如果T[ i ] = P[ j ],则i++, j++,表示目前匹配

    如果T[ i ] != P[ j ]

      如果 j == -1,则需要 i++, j++,j++ 表示P 从0开始匹配,i++表示当前不匹配,从下一个位置开始匹配。

      如果 j != -1,则从后缀字符串与前缀字符串已经匹配,令 j = next[j]即可。

    循环结束,当 j == strlen(p)时,表示完全匹配,此时返回 i - j 表示匹配的起始位置。

    例:主字符串:"abababcab",子字符串:"ababc"

    匹配过程:

    为了简化计算,引入next数组记录 j 索引处 PMT[ j - 1 ]的数值。

    代码实现

    int KMP(char * t, char * p) 
    {
        int i = 0; 
        int j = 0;
    
        while (i < strlen(t) && j < strlen(p))
        {
            if (j == -1 || t[i] == p[j]) 
            {
                i++;
                       j++;
            }
             else 
                       j = next[j];
            }
    
        if (j == strlen(p))
           return i - j;
        else 
           return -1;
    }

    4. PMT, next实现过程

    通过移动与自身字符串匹配求next:

    注意:如果不匹配,j 的值应该设为:next[j],继续向下匹配,直到为 j = -1 为止再从0开始匹配,下图说明了原因。

     

    代码实现:

    void getNext(char * p, int * next)
    {
        next[0] = -1;
        int i = 0, j = -1;
    
        while (i < strlen(p))
        {
            if (j == -1 || p[i] == p[j])
            {
                ++i;
                ++j;
                next[i] = j;
            }    
            else
                j = next[j];
        }
    }
  • 相关阅读:
    Angular2新人常犯的5个错误
    好爱情,坏爱情
    关于css中a标签的样式
    移动端rem布局实践
    我们这一代人的困惑
    原创ui.router源码解析
    Web客户端数据存储学习笔记——Cookie
    喝汤了——如何用一年时间获得十年的能力和经验
    Petya勒索木马
    推荐几个精致的web UI框架
  • 原文地址:https://www.cnblogs.com/feng-ying/p/11220443.html
Copyright © 2011-2022 走看看