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

    引言

    字符串匹配问题在OI中比较常见,我们可以比较暴力的进行求解,这样的时间复杂度为$O(n^2)$,但这种方法并不比适用与大部分情况,因为它太慢了。于是就有三个$dalao$提出了更加快速的方法来解决这个问题。他们三个的名字的首字母分别是K、M、P,所以这种算法就简称为KMP算法。

    KMP算法

    KMP算法的时间复杂度是$O(n+m)$,甩朴素的算法十条街。但是他也比较难理解,而且题目的难度也不低,所以有些恶心。我在学习的时候没有找着多少好理解的文章。唯有阮一峰的写的好理解

    所以今天写这篇随笔的主要目的是帮助大家更好的理解KMP算法。

    实现原理

    KMP算法的核心在于一个next数组。我们先不说这个数组是干什么用的。

    先来看看为什么朴素的算法时间复杂度会这么高

     

    ABCDABDABCCA

    ABDAB

    对于上面这个例子,我们来模拟一下。上面是文本串,下面是模式串。

    step 1

    先比较第一位,然后逐位进行比较直到出现不相同的一位。

    最后比较到第三位停止,因为第三位上的字符不相同

    step 2

    然后进行模式串的后移操作。直到开始出现相同的位。

    下面是模拟的过程

    这里我们进行了一共四次操作才完成。这就是高时间复杂度的根源所在

    ABCDABDABCCA

     ABDAB

    ABCDABDABCCA

      ABDAB

    ABCDABDABCCA

       ABDAB

    ABCDABDABCCA

        ABDAB

    step 3

    然后重复第一步第二步的操作,直到出现匹配的文本串子串位置(这里假设只是判断能不能匹配)。

    再说KMP

    再说KMP算法,KMP算法对第二步进行了优化。它预处理了一个next数组,这个数组表示的是模式串中前缀和后缀的最长的相同子串的长度

    那么我们在后移模式串的时候就可以将其后移(模式串长度 - next值)位来减小时间复杂度。这个next数组就通过对模式串自己匹配自己来求

    代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    const int maxn = 1e6+3;
    
    using namespace std;
    
    char T[maxn], s[maxn];
    int n, m, next[maxn], p;
    
    inline void Getnext() {
    	for(int i=2; i<=m; i++) {
    		p = next[i-1];
    		while(p && s[i] != s[p+1]) p = next[p];
    		if(s[i] == s[p+1]) next[i] = p + 1;
    		else next[i] = 0;
    	}
    }
    
    int main() {
    	scanf("%s%s", T+1, s+1);
    	n = strlen(T+1), m = strlen(s+1);
    	Getnext();
    	p = 0;
    	for(int i=1; i<=n; i++) {
    		while(p && T[i] != s[p+1]) p = next[p];
    		if(T[i] == s[p+1]) p++;
    		else p = 0;
    		if(p == m) printf("%d
    ", i-m+1), p = next[p];
    	}
    	for(int i=1; i<=m; i++) {
    		printf("%d ", next[i]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Python中if __name__ == '__main__':作用
    mac 用macports给python装opencv
    (转)学习&使用技术的四种层次
    图像处理入门,一些简单的基于像素几何变换和实现
    基于水平投影,垂直投影的字符图像分割思路和代码实现
    转:Cannot make a static reference to the non-static解决办法
    BP神经网络学习和c++例子程序代码
    python中初始化一个数组用来存储多张图片
    假期第二周周总结
    假期第一周周总结
  • 原文地址:https://www.cnblogs.com/bljfy/p/9409442.html
Copyright © 2011-2022 走看看