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;
    } 
  • 相关阅读:
    传入采购订单项目建交货单
    20190615 NACE关于采购订单的输出类型
    参照UB单创建DN并过账
    【S/4系列专栏】关于S/4你想知道的问题与答案
    数据结构(1)栈的自定义实现
    iOS开发之Todo List for Swift项目
    算法手记(2)Dijkstra双栈算术表达式求值算法
    HttpWebRequst中https的验证处理问题
    温故知新系列
    windows phone开发-windows azure mobile service使用入门
  • 原文地址:https://www.cnblogs.com/heqingyu/p/10446587.html
Copyright © 2011-2022 走看看