zoukankan      html  css  js  c++  java
  • KMP算法

    KMP算法是一种高效的字符串匹配算法。

    KMP算法的特点是给定一个主串,给定一个匹配串,问匹配串在主串中出现的次数,匹配串在主串中出现的位置等。

    首先我们先看一种暴力的方法——按位对比,若匹配失败从头再来。

    我们用两个指针,一个指针i指在主串,一个指针j指在匹配串,

    如果s1[i+1]!=s2[j+1],根据暴力的思想就从头开始匹配,i=匹配开头+1,j=1;

    显然这么不优,这样太过暴力,KMP算法的核心思想就是对于匹配失败后j的位置做一个优化。

    我们来看下面这种情况

    s1='aabaac' s2='aabaabaac'

    当i=j=5的时候 显然s[i+1]!=s[j+1];

     若是按照原来暴力的想法此时应把匹配串的j调整为1,i调整为匹配开头+1;

    但我们发现匹配串有个性质就是部分回文,s1的前五个元素为aabaa,此时如果把i++,j=3便可继续匹配。

    利用这个性质,我们可以对原方法有一个很大的优化即——KMP算法。

    KMP的核心是预处理一个fail数组即确定匹配失败后,j指针应该调整到哪个位置。

    预处理的方法就是自我匹配,显然fail[1]=0;

    1 int s2_len=strlen(s2+1);
    2 int j=1;
    3 for(int i=1;i<=s2_len;i++)
    4 {
    5     while(s[i]!=s[j+1]&&j>0) j=fail[j];
    6     if(s[i]==s[j+1]) j++;
    7     fail[i]=j;
    8 }

    然后匹配匹配串与主串即可。

    全部代码洛谷P3375

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 
     6 using namespace std;
     7 
     8 int kmp[1000005],n,m;
     9 char s1[1000005],s2[1000005];
    10 
    11 int main()
    12 {
    13     scanf("%s%s",s1+1,s2+1);
    14     n=strlen(s1+1);
    15     m=strlen(s2+1);
    16     kmp[1]=0;
    17     int j=0;
    18     for(int i=2;i<=m;i++)
    19     {
    20         while(j&&s2[j+1]!=s2[i]) j=kmp[j];
    21         if(s2[j+1]==s2[i]) j++;
    22         kmp[i]=j;
    23     }
    24     j=0;
    25     for(int i=1;i<=n;i++)
    26     {
    27         while(j&&s1[i]!=s2[j+1]) j=kmp[j];
    28         if(s2[j+1]==s1[i]) j++;
    29         if(j==m)
    30         {
    31             printf("%d
    ",i-m+1);
    32             j=kmp[j];
    33         }
    34     }
    35     for(int i=1;i<=m;i++)
    36        printf("%d ",kmp[i]);
    37     return 0; 
    38 }
  • 相关阅读:
    一行代码更改博客园皮肤
    fatal: refusing to merge unrelated histories
    使用 netcat 传输大文件
    linux 命令后台运行
    .net core 使用 Nlog 配置文件
    .net core 使用 Nlog 集成 exceptionless 配置文件
    Mysql不同字符串格式的连表查询
    Mongodb between 时间范围
    VS Code 使用 Debugger for Chrome 调试vue
    css权重说明
  • 原文地址:https://www.cnblogs.com/Hoyoak/p/11431556.html
Copyright © 2011-2022 走看看