美文网首页
KMP算法学习

KMP算法学习

作者: KomalZheng | 来源:发表于2017-07-23 09:26 被阅读6次

先引两篇看过的文章:

http://blog.csdn.net/v_july_v/article/details/6545192

http://blog.csdn.net/v_july_v/article/details/7041827

里面介绍得不错。
KMP算法的关键在于next[j]函数,明白了这个,才会真正掌握KMP算法。
这里只想写写自己对next[j]函数的分析。

【问题背景】S中寻找子串P
【关键】求出P的next[j]函数
k=next[j]函数表示的意思首先要明白: 在S[i]与P[j]不匹配的时候,S[i]继续和P中的项P[k]进行匹配(当然k!=-1);
k=next[j]函数蕴含的意思也要明白:P[0:k-1]和P[j-k:j-1]是相互匹配的最长子串;

弄明白以上两点,一切问题迎刃而解:
我们的目的不就是已知0:j时的next[j]求next[j+1]吗?
那么先令k=next[j];且假设S[i+1]不匹配P[j+1],下面求next[j+1]。
考虑
P[j]==P[k], 那么在加上已知的【关键】2 我们知道 P[0:k]和P[j-k:j]匹配,但此时,我们还关心P[j+1]和P[k+1]是否相等:如果P[j+1]!=P[k+1],意味着P[0:k]和P[j-k:j]这是最长的匹配子段,那么S[i+1]下一个需要进行匹配的项是P[k+1],即知道next[j+1]=k+1;
如果P[j+1]==P[k+1],而已知S[i+1]!=P[j+1],那么有S[i+1]!=P[k+1],于是S[i+1]就不需要和P[k+1]进行比较(但是我们知道S[i-k:i]和P[0:k]是相互匹配的(S[i-j:i]和P[0:j]匹配,再加上下滑线的部分: P[0:k]和P[j-k:j]匹配 可得)),于是由于S[i+1]不匹配P[k+1]而需要“更改下一个匹配项”,而这个匹配项,按照定义即next[k+1],因此next[j+1]=next[k+1];

P[j]!=P[k],那么首先由【关键】2得 P[0:k-1]和P[j-k:j-1]是相互匹配的,但是下一项P[k]和P[j]不匹配,看到了吗?如果把P[0:k]看成子串P',把P[0:j]看成S',那么此时j项不匹配k项的时候,j项下一个去匹配的应该是哪项?对了,是next[k](因此要让k=next[k],回到1.,目的是使得P[j]==P[k],这样,才能求出next[j+1]);

这就是整个next[j+1]函数的由来.
代码看看今晚能不能自己写出来。
HX 2013-1-16.

#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;

void GetNext(char const* p, int plength, int* next)
{
    int j = 0;
    int k = -1;
    next[j]=-1;
    while(j<plength-1)
    {
        if(k==-1||p[j]==p[k])
        {
            ++j;
            ++k;
            if(p[j]!=p[k])
            {
                next[j]=k;
            }
            else
            {
                next[j]=next[k];
            }
        }
        else
        {
            k = next[k];
        }
    }

}
int KMPAlgorithm(char const* s, int slength, char const* p, int plength,int* next)
{
    int i=0;
    int j=0;
    while(i<slength&&j<plength)
    {
        if(j==-1||s[i]==p[j])
        {
            ++i;
            ++j;
        }
        else
        {
            j=next[j];
        }
    }
    if(j>=plength)
    {
        return i-plength;
    }
    else
    {
        return -1;
    }
}
int _tmain(int argc, _TCHAR* argv[])
{
    string sstring = "aabbacbcabababbababccc";
    string pstring = "ababc";
    int* next = new int [pstring.size()];
    GetNext(pstring.data(),pstring.size(),next);
    for(int i=0;i<pstring.size();i++)
    {
        cout<<next[i]<<"\t";
    }
    cout<<endl;
    int kmpResult = KMPAlgorithm(sstring.data(),sstring.size(),pstring.data(),pstring.size(),next);
    cout<<"返回值"<<kmpResult<<endl;
    cout<<"子串为:"<<sstring.substr(kmpResult,pstring.size())<<endl;
    system("pause");
    delete[] next;
    return 0;
}

【结果】

1.jpg

相关文章

  • KMP 专题整理

    KMP 学习记录 kuangbin专题十六——KMP KMP 学习总结 朴素 KMP 算法 拓展 KMP 算法(E...

  • 对KMP算法的一些理解

    最近学到KMP算法,下面讲讲对KMP算法的一些个人理解,希望对大家有帮助! 对于KMP算法的理解: 整个KMP算法...

  • KMP算法文章合集

    字符串的查找:朴素查找算法和KMP算法 暴力匹配算法与KMP算法(串的匹配) 字符串查找算法BF和KMP 字符串匹...

  • 串的模式匹配算法

    KMP算法 算法匹配

  • 问答|KMP算法学习笔记

    问题 目录KMP是什么,做什么用的KMP算法的高效体现在哪如何KMP算法的next数组KMP的代码KMP的时间复杂...

  • KMP算法——寻找子串位置

    KMP算法——寻找子串位置 1、KMP算法简介: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J....

  • 字符串匹配 - KMP算法

    前面我们介绍非常高效的 BM 算法,今天我们介绍另一个非常出名且高效的 KMP 算法。 KMP 算法思想 KMP ...

  • kmp 算法

    前言: 少 kmp 多学习 0X00 算法板子 831. KMP字符串 感觉还是很难理解

  • KMP算法及优化

    转载请注明出处: KMP算法及优化 今天看到同学在复习数据结构书上的KMP算法,忽然发觉自己又把KMP算法忘掉了,...

  • KMP算法(字符串匹配问题)

    一、是什么? 注意,是KMP算法,不是MMP哈,我没有骂人。KMP算法是用来做字符串匹配的,除了KMP算法分,还有...

网友评论

      本文标题:KMP算法学习

      本文链接:https://www.haomeiwen.com/subject/jnlevttx.html