zoukankan      html  css  js  c++  java
  • 论KMP

    一、算法简介

    KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,

    因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。

    KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。

    具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。

    (博主很懒所以扒了百度词条的简介QAQ

    二、算法原理&流程

    首先我们对于模式串和主串的暴力匹配,无非是做一次1-n的循环,

    对于每个i,都枚举一个1-m,对于A[i-j+1...i]和B[1....j]都必须匹配

    当j=m时,则满足了模式串与主串匹配

    现在我们考虑,当一次匹配失败后,是否有可以继承的东西,以便于在下一次查找中更加快速呢?

    我们发现当A[i-j+1....i+1]与B[1....j+1]不匹配时,可以考虑减小j值,

    使得A[i-j+1...i]与B[1....j]保持匹配并继续匹配A[i+1]与B[j+1]

    仔细思考后发现,我们需要在B[1...j]中找出最大的k,使得B[1...k]与B[m...m-k+1](后缀)完全相等

    于是我们就将模式串做“自我匹配”,使得算法能够更加快速的进行,自我匹配的过程等会说

    当我们不停地寻找更小的k,然而一直不能满足条件直到k=0时,我们就不停地i++,直到A[i]=B[1],再重复前面的流程

    三、nxt数组(即跳转数组)的求值 

    这里定义一个数组P,表示当模式串匹配到下标J时,而j+1与A串不匹配,这时最大的k

    接下来开始计算数组P

    我们对于一个未知的P[j],与许多已知的P[1...j-1],是可以通过P[1....j-1]来得到P[j]的,具体如下:

    我们对于一个新的P[j],如果要直接从P[j-1]继承的话,就需要满足B[P[j-1]+1]=B[j]

    如果不满足以上条件的话,那么我们考虑将指针k(初始为j-1)移到P[j-1]上,接着开始匹配B[k+1]=B[j],直到满足

    如果一直不能匹配的话,那么P[j]=0;如果能够匹配的话,P[j]=P[k]+1;

    四、例题(luoguP3375)

    地址: https://www.luogu.org/problemnew/show/P3375

    #include<bits/stdc++.h>
    using namespace std;
    char A[1000010];
    char B[1000010];
    int n,m,p[1000010];
    int j=0;
    int main(){
        scanf("%s%s",A+1,B+1);
        n=strlen(A+1);m=strlen(B+1);
        for(int i=2;i<=m;i++){
            while(j&&B[j+1]!=B[i]) j=p[j];
            if(B[j+1]==B[i]) j++;
            p[i]=j;
        }
        j=0;
        for(int i=1;i<=n;i++){
            while(j&&B[j+1]!=A[i]) j=p[j];
            if(B[j+1]==A[i]) j++;
            if(j==m){printf("%d
    ",i-m+1);j=p[j];} 
        }
        for(int i=1;i<=m;i++)printf("%d ",p[i]);
        return 0;
    } 
  • 相关阅读:
    数据结构(四十)平衡二叉树(AVL树)
    数据结构(三十九)二叉排序树
    数据结构(三十八)静态查找表(顺序查找、二分查找、插值查找、斐波那契查找、线性索引查找)
    数据结构(三十七)查找的基本概念
    数据结构(三十六)关键路径
    数据结构(三十五)拓扑排序
    数据结构(三十四)最短路径(Dijkstra、Floyd)
    数据结构(三十三)最小生成树(Prim、Kruskal)
    字符串匹配算法之KMP
    最长公共子序列(Longest common subsequence)
  • 原文地址:https://www.cnblogs.com/heqingyu/p/10446587.html
Copyright © 2011-2022 走看看