kmp

关于KMP的一点思考

删除回忆录丶 提交于 2019-12-04 08:16:43
关于KMP的一点思考 KMP的 \(next\) 数组的性质很精妙,有必要开一个坑学习一下 Part 1 啥是next \(next[i]\) 表示对于 \(pre_i\) 这个字符串,这个抠出来的字符串本身后缀和前缀相等的最长长度。是一个自变量 只和这个子串有关的函数 。这点很重要 由于保证了是最长长度,这个数有一些优良的性质,常常在关于一个串的循环表示或者周期表示中发挥作用。 注意到这个 \(next[i]\) 虽然代表是这个最长长度,但是值得注意的是,由于字符串从1开始编号,所以这个值也是那个前缀的下标。 Part2 如何求next 边界条件是, \(nx[1]=0\) 。考虑我们若已经求得前面 \(i-1\) 的位置的 \(nx\) 值,现在如何求 \(nx[i]\) 。 把 \(S[1\dots i-1]\) 看做一个整体,现在我们在后面加入了一个字符 \(S[i]=c\) 。 我们现在就是要在 \(pre_{nx[i-1]}\) 中截一个最大的位置 \(p\) ,使得 \(S[p+1]=c\) ,而 \(p\) 虽然是下标,但是由于从 \(1\) 开始编号那么就同时就是这个串的长度,所以 \(nx[i]=p+1\) 。为什么是在 \(pre_{nx[i-1]}\) 中找呢?因为我们要保证 \(S[i-p+1...i]=S[1,p]\) 。 所以如何找 \(p\) 呢

KMP几道入门题目

北战南征 提交于 2019-12-04 00:46:52
HDU 1711 Number Sequence(模板题) #include<stdio.h> #include<string> const int maxn=1e6+10; const int maxm=1e4+10; int t,n,m,s[maxn],p[maxn]; int next[maxm]; void GetNext() { int plen=0; int slen=-1; next[0]=-1; while(plen<m) { if(slen==-1||p[plen]==p[slen]) { plen++;slen++; if(p[plen]!=p[slen])next[plen]=slen; else next[plen]=next[slen]; } else slen=next[slen]; } } int kmp() { int plen=0; int slen=0; while(plen<m&&slen<n) { if(plen==-1||p[plen]==s[slen]) { plen++;slen++; } else plen=next[plen]; } if(plen==m) return slen-plen+1; else return -1; } int main() { scanf("%d",&t); while(t--) { scanf("%d

KMP算法详解

╄→尐↘猪︶ㄣ 提交于 2019-12-03 20:27:16
前置:    尝试去思考这样一个问题:给定字符串S和P,询问在字符串S中,字符串P出现了几次?    设S = "aabcdedf", P = "abc";    我们先从最暴力的方法入手,不难想到去针对S的每一位去和P暴力匹配。    当 $i = 0$ 时, 字符串匹配如下图:       $s[0] == p[0]$ 则继续向后匹配,发现 $s[1] != p[1] $,则执行 $i++$ 进行下一次匹配。    当 $i = 1$ 时,匹配如下图       $s[0] == p[0]$ 继续向后匹配, 直到 $s[i + strlen(p) - 1] == p[strlen(p) - 1]$ 证明匹配成功。    令 $ans++$,并且 $i++$ 进行下一次匹配。    按上述方法匹配直到字符串S被遍历一遍,输出 $ans$ 即可。    代码: 1 int fun(char *s, char *p){ 2 int ans = 0; 3 for (int i = 0; i < strlen(s); ++i){ 4 int j = 0; 5 for (; j < strlen(p); ++j){ 6 if (s[i + j] == p[j]) 7 continue; 8 else 9 break; 10 } 11 if (j == strlen(p)) 12 ++ans

POJ3461题解——KMP入门

对着背影说爱祢 提交于 2019-12-03 13:17:18
题目链接: http://poj.org/problem?id=3461 The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e' . He was a member of the Oulipo group. A quote from the book: Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où

.gvs (GuideView openmp statistics) file format

匿名 (未验证) 提交于 2019-12-03 10:24:21
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试): 问题: Is there a format of *.gvs files, used by GuideView OpenMP performance analyser? The "guide.gvs" is generated, f.e. by intel's OpenMP'ed programmes with $ export LD_PRELOAD=<path_to_icc_or_redist>/lib/libiompprof5.so $ ./openmp_parallelized_prog $ ls -l guide.gvs 回答1: It s a plain text. Here is an example of such from very short omp programme: $ cat guide.gvs *** KAI statistics library k3301 *** Begin Task 0 Environment variables: OMP_NUM_THREADS : 2 OMP_SCHEDULE : static OMP_DYNAMIC : FALSE OMP_NESTED : FALSE KMP_STATSFILE : guide.gvs KMP

串的两种模式匹配方式(BF/KMP算法)

╄→гoц情女王★ 提交于 2019-12-03 09:55:23
前言 串,又称作字符串,它是由0个或者多个字符所组成的有限序列,串同样可以采用顺序存储和链式存储两种方式进行存储,在主串中查找定位子串问题(模式匹配)是串中最重要的操作之一,而不同的算法实现有着不同的效率,我们今天就来对比学习串的两种模式匹配方式: 朴素的模式匹配算法(Brute-Force算法,简称BF算法) KMP模式匹配算法 朴素的模式匹配算法(BF算法) BF算法是模式匹配中的一种常规算法,它的思想就是: 第一轮 :子串中的第一个字符与主串中的第一个字符进行比较 若相等 ,则继续比较主串与子串的第二个字符 若不相等 ,进行第二轮比较 第二轮 :子串中的第一个字符与主串中第二个字符进行比较...... 第N轮 :依次比较下去,直到全部匹配 图示说明: 第一轮: 第二轮: ...... 原理一致,省略中间步骤 第五轮: 第六轮: 代码实现: 看完文字与图例讲解,我们来动手实现一个这样的算法 简单归纳上面的步骤就是: 主串的每一个字符与子串的开头进行匹配,匹配成功则比较子串与主串的下一位是否匹配,匹配失败则比较子串与主串的下一位,很显然,我们可以使用两个指针来分别指向主串和子串的某个字符,来实现这样一种算法 匹配成功,返回子串在主串中第一次出现的位置,匹配失败返回 -1,子串是空串返回 0 int String::bfFind(const String &s, int pos)

(模板)poj3461(kmp模板题)

℡╲_俬逩灬. 提交于 2019-12-03 07:16:06
题目链接:https://vjudge.net/problem/POJ-3461 题意:给出主串和模式串,求出模式串在主串中出现的次数。 思路:kmp板子题。 AC代码: #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=1e6+5; int T,next[maxn],len1,len2; char s1[maxn],s2[maxn]; //得到next数组 void get_next(){ next[0]=-1; int j=-1; for(int i=1;i<len2;++i){ while(j>-1&&s2[j+1]!=s2[i]) j=next[j]; if(s2[j+1]==s2[i]) ++j; next[i]=j; } } //输出模式串在主串上依次出现的下标 void kmp_index(){ int j=-1; for(int i=0;i<len1;++i){ while(j>-1&&s1[i]!=s2[j+1]) j=next[j]; if(s1[i]==s2[j+1]) ++j; if(j==len2-1){ j=next[j]; printf("%d\n",i-len2+1); } } } //返回模式串在主串上出现的次数

HDU 2087 剪花布条 (KMP)

不问归期 提交于 2019-12-03 04:52:44
题目链接: HDU 2087 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。 Output 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。 Sample Input abcde a3 aaaaaa aa # Sample Output 0 3 Source 冬练三九之二 Solution 题意 如题。 思路 KMP 裸题,每次匹配成功后模式串指针指向模式串首就行了。 Code #include <bits/stdc++.h> using namespace std; int pi[1010]; void prefix_function(string s) { memset(pi, 0, sizeof(pi)); for(int i = 1; i < s

KMP字符串匹配 模板 洛谷 P3375

北战南征 提交于 2019-12-03 02:05:28
KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。 为了减少骗分的情况,接下来还要输出子串的前缀数组next。 (如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。) 样例: 输入 ABABABC ABA 输出 1 3 0 0 1 解题思路 当然是使用KMP啦,只不过这个要求比较高一些。 注意这里要输出的next数组内容是不能进行优化的那种,否者就会WA,带有优化的那种看第二个代码。 详情见代码。这个也可以算作一个模板了。 代码实现 void getnext() //做的第一步是获得next【】的值 { int i=0,k=-1; next[0]=-1; while(i<lenb) { if(k==-1)//这里和平常的有些不同,这里进行了一些优化,将两个条件分开了。 { next[++i]=++k; continue; } if (b[i]==b[k]) { if(b[i+1]==b[k+1]) //这里进行了优化,一般介绍KMP的文章中都有会这个。 next[++i]=next[++k]; else next[++i]=++k; } else k=next[k]; } } #include<cstdio> #include<cstring> using namespace

KMP浅谈

坚强是说给别人听的谎言 提交于 2019-12-03 01:20:44
关于KMP ​ KMP其实是三个人名字的缩写,因为是他们同时发现的 (大佬惹不起) ; ​ KMP作为CSP考点,主要亮点是其优秀的匹配复杂度,而且消耗空间小,比起hash虽然有些局限性,但是因为其正确率高,所以经常被人使用. 前置知识 ​ 关于字符串的读取,以及字符串相关操作的基础了解,这里涉及字符串匹配以及子串; 入坑 ​ 其实KMP并不困难,只是让人难受的是它比较抽象的数组跳跃,我想这个并不需要过多解释; 思想 ​ KMP常用于一个字符串是否出现在另一个字符串中.我们知道,如果暴力匹配了话,每次失配时就必须重新开始(不能贪心地从失配位置匹配),这样造成很大的浪费,那么我们想从已经匹配过的字符串中提取一些信息,以至于让我们不跳那么远,那这怎么办? ​ KMP算法就由此诞生了,它通过记录模式串的内部信息,为匹配时提供信息,可以节省大量时间. 模版 #include<iostream> #include<cstring> #define maxn 1000007 using namespace std; int t,nxt[maxn],l1,l2,ans; char s1[maxn],s2[maxn]; void get_nxt(){ int t; nxt[0]=-1; for(int i=1;i<l2;i++){ t=nxt[i-1]; while(s2[i]!=s2[t+1]&