首页 > 其他分享 >从KMP到ExKMP

从KMP到ExKMP

时间:2023-02-14 16:11:50浏览次数:30  
标签:ExKMP 字符 int 复杂度 枚举 KMP 字符串

  • KMP

    KMP算法全称Knuth-Morris-Pratt算法,可以在\(O(n + m)\)的时间复杂度下进行在长度为\(n\)的字符串中查找另一个长度为\(m\)的字符串出现的所有位置,同时也能在\(O(n)\)的时间复杂度下查找一个长度为\(n\)的字符串中,前缀和后缀相同的最大长度。
    首先思考一下,如何暴力地在一个字符串中查找另一字符串出现的所有位置,很快可以找到这样一种思路:枚举字符串\(s1\)中所有字符\(s1[i]\)作为要查找的字符串\(s2\)的首个字符,然后向后遍历判断这个字符之后是否存在\(s2\),实现代码如下:
#include <iostream>
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	string a, b;
	int ans = 0;
	cin >> a >> b;
	int la = a.length(), lb = b.length();
	for (int i = 0; i < la; ++i) {
		if (a[i] == b[0]) {
			for (int j = 0; j < lb; ++j) {
				if (a[i + j] != b[j])  break;
				if (j == lb - 1) ++ans;
			}
		}
	}
	cout << ans << endl;
	return 0;
}

显然,此时程序的复杂度是\(O(nm)\)的,有位大佬曾言:

“算法时间复杂度的优化本质上就是减少无用的操作”

我们可以发现,在上一个代码中,当我们枚举一个字符\(s[i]\)时,这个字符很可能在我们枚举\(s[i-1]\)的时候就被枚举过了,所以我们要对这一部分操作进行精简。
我们引入一个数组\(nxt[i]\),表示在字符串\(s1[0\sim i]\)中,前缀和后缀相等的最大长度。
所以当我们模式串匹配文本串出现失配时,我们要跳到这个位置对应的\(nxt\),也就是后面匹配不上时,就回到前面与已匹配

标签:ExKMP,字符,int,复杂度,枚举,KMP,字符串
From: https://www.cnblogs.com/Kazdale/p/17119930.html

相关文章

  • 【LeetCode字符串#06】KMP巩固练习:重复子串
    重复的子字符串力扣题目链接(opensnewwindow)给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。......
  • BF算法与KMP算法
    1.BF算法BF算法,即暴力(BruteForce)算法,是普通的【模式匹配】算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二......
  • 【LeetCode字符串#05】基于个人理解的KMP算法图解,以及应用到strStr()函数实现
    KMP算法(用于实现strStr())strStr()函数是用来在一个字符串中搜索是否存在另一个字符串的函数,其匹配字符串方式为KMP算法KMP算法基础理论假设有如下两个字符串文本串......
  • KMP学习笔记
    板:P3375【模板】KMP字符串匹配时间复杂度:O(n+m)定义一个nxt数组:解析咕了有时间补贴个代码:这里说下KMP的一些应用:1.字符串配对(本职工作)P1470[USACO2.3]最长前......
  • Period POJ - 1961(kmp,最小循环节)
    题意:给定一个字符串,ascii码在97到126之间(字母)如果前i个字符组成的字符串是由子字符串循环一定次数组成的,则该字符串为周期串,子字符串为循环节。比如aabaabaabaab,在前两个字......
  • Number Sequence HDU - 1711(kmp模板)
    AC代码:#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>usingnamespacestd;constintmaxn=1e7;ints[maxn],p[maxn],nxt[maxn];intn,m;voi......
  • Power Strings POJ - 2406(kmp最小循环节)
    AC代码:#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<algorithm>usingnamespacestd;constintmaxn=1e6+5;strings;intnxt[maxn]......
  • Cyclic Nacklace HDU - 3746 (kmp最小循环节)
    题意:现在给你一个字符串,请问在该字符串末尾最少添加多少个字符,可以让这个字符串获得重复循环序列。AC代码:#include<iostream>#include<cstring>usingnamespacestd;const......
  • 前缀函数与 KMP
    前缀函数概述前缀函数\(\pi_i\)为\(s_{1\dotsi}\)的真前后缀最大相同长度。这里的所有\(s\)下标从\(1\)开始,长度为\(n\)。实现原理首先肯定能想到......
  • KMP
    一、问题​ 给出两个字符串\(s_1\)和\(s_2\),若\(s_1\)的区间\([l,r]\)子串与\(s_2\)完全相同,则称\(s_2\)在\(s_1\)中出现了,其出现位置为\(l\)。现在请你......