关闭

KMP算法学习

标签: 算法
201人阅读 评论(0) 收藏 举报
分类:

http://www.cnblogs.com/c-cloud/p/3224788.html作者这篇文章讲的真是好,虽然匹配代码跳转部分看不懂,作者说这部分是关键….

这里写图片描述
“部分匹配值”就是”前缀”和”后缀”的最长的共有元素的长度。以”ABCDABD”为例,

  - “A”的前缀和后缀都为空集,共有元素的长度为0;

  - “AB”的前缀为[A],后缀为[B],共有元素的长度为0;

  - “ABC”的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

  - “ABCD”的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

  - “ABCDA”的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为”A”,长度为1;

  - “ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为”AB”,长度为2;

  - “ABCDABD”的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。
  

移动位数 = 已匹配的字符数 - 对应的部分匹配值 (该题中移动位数6-2=4)

#include<stdio.h>
#include<string.h>
void makeNext(const char P[],int next[])
{
    int q,k;//q:模版字符串下标;k:最大前后缀长度
    int m = strlen(P);//模版字符串长度
    next[0] = 0;//模版字符串的第一个字符的最大前后缀长度为0
    for (q = 1,k = 0; q < m; ++q)//for循环,从第二个字符开始,依次计算每一个字符对应的next值
    {
        while(k > 0 && P[q] != P[k])//递归的求出P[0]···P[q]的最大的相同的前后缀长度k
            k = next[k-1];          //不理解没关系看下面的分析,这个while循环是整段代码的精髓所在,确实不好理解  
        if (P[q] == P[k])//如果相等,那么最大相同前后缀长度加1
        {
            k++;
        }
        next[q] = k;
    }
}

int kmp(const char T[],const char P[],int next[])
{
    int n,m;
    int i,q;
    n = strlen(T);
    m = strlen(P);
    makeNext(P,next);
    for (i = 0,q = 0; i < n; ++i)
    {
        while(q > 0 && P[q] != T[i])
            q = next[q-1];
        if (P[q] == T[i])
        {
            q++;
        }
        if (q == m)
        {
            printf("Pattern occurs with shift:%d\n",(i-m+1));
        }
    }    
}

int main()
{
    int i;
    int next[20]={0};
    char T[] = "ababxbababcadfdsss";
    char P[] = "abcdabd";
    printf("%s\n",T);
    printf("%s\n",P );
    // makeNext(P,next);
    kmp(T,P,next);
    for (i = 0; i < strlen(P); ++i)
    {
        printf("%d ",next[i]);
    }
    printf("\n");

    return 0;
}
0
0
查看评论

KMP算法应用

KMP算法应用题目描述: 给定一个字符串,求其中出现重复的任意一个字符?再求其中最长的重复子串?题目分析: 如果明白KMP原理,明白next数组next[j]=k的具体含义,这样的题目可以用next数组来求解。next[j]=k,表示在模式串p中第j个字符前有长度为k的相同前缀和后缀。相同的前缀...
  • zxc995293774
  • zxc995293774
  • 2015-07-29 20:38
  • 557

kmp算法总结

搞ACM也有三年了,期间学习了不少算法,到12月把上海站打完也要成退役狗了。最近突然想把学过的一些算法回过头来好好总结一下,于是就有了我的算法总结系列。这是这个系列的开端,所以先写一个简单点的算法,以后会慢慢复习一些复杂的算法,最后还是希望自己能够坚持下去吧。 KMP算法 KMP算法是一种线性时间...
  • dyx404514
  • dyx404514
  • 2014-11-20 16:00
  • 3475

KMP算法的效率分析

上一节,我们研究了KMP算法的实现原理,这节,我们从分析的角度看看KMP算法的时间复杂度,通过分析证明,我们代码对算法的实现,是能保证线性复杂度的
  • tyler_download
  • tyler_download
  • 2016-10-20 12:55
  • 646

KMP算法next数组通俗理解,适合考研及基础学习者

KMP算法是主要用来做字符串的匹配,有一个文本次T和一个模式串P,就是拿模式串P去匹配文本串T。 匹配的步骤分为两步,先做模式串自身匹配,即求出next数组;然后在进行T与P的匹配。 那么可能会问,为什么要做模式串自身匹配,这么做的优点体现在哪里?     ...
  • wust_ZJX
  • wust_ZJX
  • 2016-11-20 00:38
  • 755

KMP简单证明

KMP第一遍不是特别容易理解,所以就琢磨着给出一个证明,来加深理解,所以就想出了下面这么个不是很正规和形式化的证明。关于KMP算法的流程可以搜索相关文章,比如这篇挺不错的。前提假设:目标文本串T的长度为n,模式串P的长度为m,A为所谓的next数组,i为在模式串的第i个位置匹配失败。 需要证明的问题...
  • feilengcui008
  • feilengcui008
  • 2016-03-03 17:45
  • 497

KMP算法到底在干什么

在写这篇文章之前参考了两篇文章,觉得写得很好,尤其是阮一峰写的KMP算法。 KMP算法的关键是它的next数组,利用next数组能够高效地确定在当前失配的情况下,应当将模式串移动多少位才能够避免不必要的匹配。不必要的匹配 如图,如果当前目标串与模式串在D处发生失配,传统方法是从模式串的开头位置重...
  • kornberg_fresnel
  • kornberg_fresnel
  • 2017-09-16 11:17
  • 246

【笔记】KMP算法相关计算题(选择题)

KMP算法的相关计算
  • Aprilxdy
  • Aprilxdy
  • 2017-09-08 11:11
  • 383

KMP算法 Next数组详解(【洛谷3375】KMP字符串匹配 )

KMP算法题面题目描述如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。为了减少骗分的情况,接下来还要输出子串的前缀数组next。如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。 输入输出格式输入格式:第一行为一个字符串,即为s1(仅包...
  • qq_30974369
  • qq_30974369
  • 2017-07-03 21:13
  • 915

KMP算法图解之过程实现

本文是图中的老人所写的中文版,作者是谁无法确定,毕竟转载已经让原作者消失在网络的海洋,不过我依然要在此表示对两位作者由衷的感谢。      读完本文,对KMP有了初步的认识,但文中对关键的部分匹配值没有讲解,后续会补充上。   ...
  • u010232171
  • u010232171
  • 2014-12-15 17:06
  • 752

KMP算法最浅显理解——一看就明白

说明KMP算法看懂了觉得特别简单,思路很简单,看不懂之前,查各种资料,看的稀里糊涂,即使网上最简单的解释,依然看的稀里糊涂。 我花了半天时间,争取用最短的篇幅大致搞明白这玩意到底是啥。 这里不扯概念,只讲算法过程和代码理解:KMP算法求解什么类型问题字符串匹配。给你两个字符串,寻找其中一个字符串...
  • starstar1992
  • starstar1992
  • 2017-02-07 17:41
  • 40753
    个人资料
    • 访问:27675次
    • 积分:572
    • 等级:
    • 排名:千里之外
    • 原创:25篇
    • 转载:14篇
    • 译文:0篇
    • 评论:4条
    文章分类
    最新评论