kmp

kmp & exkmp 模板

不羁岁月 提交于 2019-11-27 10:59:45
kmp inline void calc_next() { // 计算next数组 a为模式串 从1开始 next[1] = 0; for (int i = 2, j = 0; i <= n; ++ i) { while (j > 0 && a[i] != a[j + 1]) j = next[j]; if (a[i] == a[j + 1]) j ++; next[i] = j; } } inline void calc_f() { // kmp b为主串 从1开始 for (int i = 1, j = 0; i <= m; ++ i) { while (j > 0 && (j == n || b[i] != a[j + 1])) j = next[j]; if (b[i] == a[j + 1]) j ++; f[i] = j; if (f[i] == n) {/* the first time */} } } exkmp // 求 a 关于 b 的后缀的最长公共前缀, Next 记录 a关于自己每个后缀的最长公共前缀, ret 记录 a 关于 b 的后缀的最长公共前缀 void ExtendedKMP(char *a, char *b, int M, int N, int *Next, int *ret) { int i, j, k; for (j = 0; 1 + j <

[kuangbin专题] KMP

三世轮回 提交于 2019-11-27 10:03:42
https://vjudge.net/contest/278481 A - Oulipo 可重叠匹配,KMP裸题 1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 using namespace std; 5 const int MAXW=1e4+5; 6 const int MAXT=1e6+5; 7 char strW[MAXW],strT[MAXT]; 8 int lenW,lenT; 9 int Next[MAXW]; 10 void GetNext() 11 { 12 int k=Next[0]=-1; 13 int j=0; 14 while(j<lenW) 15 { 16 if(k==-1||strW[k]==strW[j]) Next[++j]=++k; 17 else k=Next[k]; 18 } 19 } 20 int kmp() 21 { 22 int i=0,j=0,ans=0; 23 while(i<lenT) 24 { 25 if(j==-1||strT[i]==strW[j]) ++i,++j; 26 else j=Next[j]; 27 if(j==lenW) 28 { 29 ans++; 30 j=Next[j]; 31 } 32 } 33 return ans; 34

CodeForces 1200E Compress Words

℡╲_俬逩灬. 提交于 2019-11-27 09:58:07
\(C_n^m\) 的typora,点了一下 启用源代码模式 就把我已经写好的博客弄没了,就给我留个标题,自动保存也只给我保存了个标题…… \(C_n^m\) ,wdnmd Time limit 1000 ms Memory limit 262144 kB 解题思路 KMP 打比赛的时候愣是想不到怎么用KMP,总想着如果用kmp,那么每次合并都要更新nxt数组,会被卡到n方,就是想不到老字符串不用每次都全体参与KMP,每次只需要把老字符串后面那段拿出来判断就行了……还想着是不是要用啥我现在还不会的高级玩意……对KMP的理解只停留在做最裸的那种板题…… KMP有两种玩法,目的都是在合并老字符串(之前合并的结果)和新字符串(最新读入的)的时候找出可以被合并的长度,然后就能把新字符串后面那截不能合并的接到老字符串后面。 边写边骂typora 。由于合并的时候,老字符串和新字符串重复的长度小于等于新字符串的长度,所以处理的时候都截取老字符串后面和新字符串等长的一截(如果新字符串比老字符串长,那么就选整个老字符串) 一种是 官方题解 的思路——先把新字符串放前面,把“老字符串的后面一截”放后面,然后对于这个新接的合体字符串跑一遍KMP,求出nxt数组,以便找到最长的border(这个是nxt数组的定义了),这个就是可以合并的长度了

【题解】P3375 【模板】KMP字符串匹配

我们两清 提交于 2019-11-27 07:00:48
这道题目是比较经典的 \(KMP\) 模板,用一个模式串匹配一个文本串,输出全部匹配的位置 首先考虑最暴力的做法: 我们从最开始的位置暴力匹配,如果成功,那么就返回 \(i-j\) , \(i\) 是文本串当前的位置, \(j\) 是模式串当前的位置 否则,我们就回溯到 \(i-j+1\) ,因为我们开始匹配的位置是 \(i-j\) ,那么它的下一位就是 \(i-j+1\) 复杂度为 \(O(n^2)\) 我们可以发现,当我们在匹配的过程中,我们不一定要返回到 \(i-j+1\) 开始重新匹配,能不能只让模式串动,而不让文本串动呢? 答案是有的,这就要请到我们今天的主角: \(KMP\) \(KMP\) 本质上的匹配是和暴力一样的,只不过它加了一个 \(next\) 数组,从而优化了时间复杂度。 当 \(i\) 和 \(j\) 匹配时,那么我们直接令 \(i++,j++\) ,但如果不匹配呢? 这时,我们就令 \(j=next[j]\) ,注: \(next[j]\) 表示的是 来源: https://www.cnblogs.com/Call-me-zhz/p/11349647.html

A - Number Sequence HDU - 1711 (kmp)

不打扰是莪最后的温柔 提交于 2019-11-27 05:53:27
[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher A - Number Sequence HDU - 1711 题目链接: https://vjudge.net/contest/70325#problem/A 题目: Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one. InputThe first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 <= M <= 10000, 1 <= N <=

单词(word)

半腔热情 提交于 2019-11-27 05:38:34
【问题描述】 给定一个特定的序列,这个序列由数个单词组成,现在我们知道一个加密序列,已知加 密序列一定是特定序列的一部分,找出这个加密序列在特定序列中的第一次出现的位置。 注意:加密是以替换的形式,也就是说,加密序列与特定序列中的单词必须一一对应。 【输入格式】 第一行包括数个单词,单词末尾以$作结,每个单词间相隔一个空格,表示特定序列,$不被 算作单词。 第二行格式相同,表示加密序列。 注意:每一个序列的字母数不会超过 10^6, 【输出格式】 输出加密序列在特定序列中出现的第一个单词的位置,保证答案一定存在。 【输入输出样例】 输入 a a a b c d a b c $ x y $ 输出 3 输入 a b c x c z z a b c $ prvi dr prvi tr tr x $ 输出 3 输出 3 输入 xyz abc abc xyz $ abc abc $ 输出 2 【数据说明】 对于 50%的数据,N≤1000。 对于 100%的数据,2≤N≤300000。 思路: 这题就是让我们在一个长串找一个相似的子结构,我们发现,虽然字符是不一样的,但是在同一个串中同一个字符的距离间隔应该是相同的,那么我们用距离来构造匹配串 以下面为例: a b c x c z z a b c $ prvi dr prvi tr tr x $ 生成串为: 0 0 0 0 2 0 1 7 7

KMP(next数组的更新理解)Codeforces Round #578 (Div. 2)--Compress Words

强颜欢笑 提交于 2019-11-27 04:45:47
题目链接: https://codeforc.es/contest/1200/problem/E 题意: 有n串字符串,让你连起来:sample please ease in out ---》 sampleaseinout 思路: 肯定KMP啊,但是比赛的时候对kmp的next数组一知半解,所以也不知道怎么用。 next数组其实就是对key串进行处理next(失配值),然后在母串上去匹配。 1 #define IOS ios_base::sync_with_stdio(0); cin.tie(0); 2 #include <cstdio>//sprintf islower isupper 3 #include <cstdlib>//malloc exit strcat itoa system("cls") 4 #include <iostream>//pair 5 #include <fstream> 6 #include <bitset> 7 //#include <map> 8 //#include<unordered_map> https://codeforc.es/contest/1200/problem/E 9 #include <vector> 10 #include <stack> 11 #include <set> 12 #include <string.h>/

快速字符串匹配一: 看毛片算法(KMP)

喜欢而已 提交于 2019-11-27 02:57:47
前言 由于需要做一个快速匹配敏感关键词的服务,为了提供一个高效,准确,低能耗的关键词匹配服务,我进行了漫长的探索。这里把过程记录成系列博客,供大家参考。 在一开始,接收到快速敏感词匹配时,我就想到了 KMP 翻译过来叫“看毛片“的算法,因为大学的时候就学过它。听说到它的效率非常高。把原本字符串匹配效率 O(n*m) 缩短到了O(n+m),把✖️变成了➕,真是了不得。 每次我回顾 KMP 算法时,都会发现自己是个小白,或者每次回顾时,都发现上次因为回顾而写的总结居然是错的!所以为了学习快速字符串匹配,并再次温故 KMP ,所以我决定使用 KMP 算法试一试。如果以后在面试的时候,可以将KMP 完整的写出来,那岂不是很牛逼? 孔子说过的“温故而知新” 真的是很有道理的,经过这次回顾,我觉得是时候为此写一篇全新的博客了,因为这次的理解肯定是正确的! KMP 快是因为啥呢?是因为利用了 字符串 公共前后缀的特性,加快了匹配速度,但是转念一想,敏感关键词公共前后缀相等的情况可是很少的呀。那还有必要用KMP 吗? 当然有必要了,所谓技多不压身,了解掌握一种算法准没坏处,而且还可以比较 KMP 和 C# 中 String.Contains() 的效率,开拓自己的眼界。 KMP 以前在学习 KMP 的时候,我也看了网上很多博客,关于这个算法讲解的博客是非常多的,而且讲解的都很细致。奈何我每看过一次

【模板】KMP算法

白昼怎懂夜的黑 提交于 2019-11-27 01:32:35
用途:处理字符串匹配问题 例子:给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置 时间复杂度:O(n) 变量解释: A[i]:存储A串 B[i]:存储B串 p[i]:在B串中与字母B[i]相同的上一个字母的位置 给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置 预处理p[]: void pre() { p[1]=0; int j=0; for (int i=1;i<m;i++) { while (j>0&&B[j+1]!=B[i+1]) j=p[j]; if (B[j+1]==B[i+1]) j++; p[i+1]=j; } } KMP: int kmp() { int j=0; for (int i=0;i<n;i++) { while (j>0&&B[j+1]!=A[i+1]) j=p[j]; if (B[j+1]==A[i+1]) j++; if (j==m) { printf("%d\n",i+1-m+1); j=p[j]; } } } 来源: https://blog.csdn.net/weixin_45485187/article/details/99233348

KMP

烂漫一生 提交于 2019-11-26 22:34:22
掌握重点就完全O得K。码量感人 思路: 见 030 ,讲得精炼易懂,比某博客“从头到尾彻底理解”的12048字好多了(纯粹发泄一下怨念)。注意重点理解next数组定义,与i,j的初始值即可。哦对了,其实看六个小时KMP还没看懂和看三个小时的快排感受是一样的:) 哦不我又开始吐槽了。 好吧好吧直接贴模板题和代码。 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。 为了减少骗分的情况,接下来还要输出子串的前缀数组next。如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。 输入输出格式 输入格式: 第一行为一个字符串,即为s1(仅包含大写字母) 第二行为一个字符串,即为s2(仅包含大写字母) 输出格式: 若干行,每行包含一个整数,表示s2在s1中出现的位置 接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。 输入输出样例 输入样例#1: 输出样例#1: 说明 时空限制:1000ms,128M 数据规模: 设s1长度为N,s2长度为M 对于30%的数据:N<=15,M<=5 对于70%的数据:N<=10000,M<=100 对于100%的数据:N<=1000000,M<=1000 代码 #include<cstdio> #include<iostream> #include<cstring>