kmp

hdu6153 A Secret(KMP + DP)

安稳与你 提交于 2019-12-02 06:50:31
题意: 给你两个字符串 t 和 s,然后让你计算 s的后缀在 t中出现的次数* 后缀的长度 累加的 和 。 思路: 考虑KMP ,因为 KMP 是匹配前缀的所以,需要倒转字符串。 然后设dp数组为 长度 为 i的前缀 在 t中出现 的次数 ,在 KMP 匹配的过程中,每次 dp[j] ++。但是,KMP算法为了减少 回溯,会省略相同长度字符的匹配,即Next[i] 代表着非前缀 后缀的 子串 与 该字符串前缀 匹配的最大长度,如果Next[i]非零,i 长度的 前缀 必然包含一个长度为Next[i] 的前缀 和 整个字符串的前缀匹配。 即 dp[Next[i]] += dp[i] AC Code: #include<iostream> #include<cstring> #include<queue> #include<map> #include<set> #include<stack> #include<cmath> #include<cstdio> #include<iomanip> #include<sstream> #include<algorithm> using namespace std; #define read(x) scanf("%d",&x) #define Read(x,y) scanf("%d%d",&x,&y) #define sRead(x,y,z)

KMP --关于cogs1570 乌力波

北城以北 提交于 2019-12-01 23:17:38
题目链接: http://cogs.pro:8081/cogs/problem/problem.php?pid=vQzXJkgWa 【题目描述】 法国作家乔治·佩雷克(Georges Perec,1936-1982)曾经写过一本书,《敏感字母》(La disparition),全篇没有一个字母‘e’。他是乌力波小组(Oulipo Group)的一员。下面是他书中的一段话: 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ù s’abolissait

[CSP-S模拟测试]:串串香(KMP)

孤街浪徒 提交于 2019-12-01 21:27:02
题目传送门(内部题75) 输入格式   输入文件$ccx.in$   每个输入文件包含多组测试数据。输入文件的第一行为一个整数$T$,表示数据组数。接下来$T$行,每行表示一组测试数据   每行一开始,两个空格隔开的数字$n,m$,含义见【题目描述】。之后是一个长度为$m$的字符串。 输出格式   $T$行,每行一个整数表示答案。 样例 见下发文件 数据范围与提示   对全部测试数据,$n\leqslant 10^6 ,m\leqslant 10^6 ,T\leqslant 10$,输入文件中的所有$m$之和不超过$5\times 10^6$   第$1,2$个测试点,$m=1$   第$3,4$个测试点,给出的字符串中只含有字母$'A'$   第$5,6,7,8,9,10,11$个测试点,满足$n\times m\leqslant 10^6$   第$11,12,13,14,15$个测试点,满足$m\leqslant 100$   第$16,17,18,19,20$个测试点,无特殊限制 题解 考察对$KMP$的理解。 一般情况下就是$(n-1)\times m$。 话画图会发现当串长减去最长公共前后缀是串长的一个因子时答案就是$(n-1)\times m+nxt[n]$(这里的$nxt$数组其实就是$KMP$中的$nxt$数组,即为串的公共前后缀)。 其实用$hash$也可以。

(模板) KMP

会有一股神秘感。 提交于 2019-12-01 19:25:33
—————————————————————————————————————————————————— —————————————————————前排护眼——————————————————————— —————————————————————————————————————————————————— //文本串和模式串 string str,pat; //next[i]表示模式串前i个字符组成的串其前缀后缀相通的最长长度 //也是在i出匹配失败时该跳转的位置 int next[10002]; //得到next数组 void getnext(){ int i=0,j=-1; next[0]=-1; while(i<pat.size()){ if(j==-1||pat[i]==pat[j]){ next[++i]=++j; } else j=next[j]; } } //返回文本串中模式串出现的次数 int kmp(){ int i=0,j=0,len1=str.size(),len2=pat.size(); int ans=0; while(i<len1){ if(j==-1||str[i]==pat[j]){ i++; j++; } else j=next[j]; if(j==len2)ans++; } return ans; } 来源: https://www.cnblogs

Clairewd’s message(kmp||hash)

被刻印的时光 ゝ 提交于 2019-12-01 17:04:11
Clairewd’s message Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11390 Accepted Submission(s): 4025 Problem Description Clairewd is a member of FBI. After several years concealing in BUPT, she intercepted some important messages and she was preparing for sending it to ykwd. They had agreed that each letter of these messages would be transfered to another one according to a conversion table. Unfortunately, GFW(someone's name, not what you just think about) has detected their action. He also got their conversion table by some unknown

[KMP]

安稳与你 提交于 2019-12-01 12:40:07
KMP未优化: #include <iostream> #include <string> using namespace std; /* P 为模式串,下标从 0 开始 */ void GetNext(string P, int next[]) { int p_len = P.size(); int i = 0; // P 的下标 int j = -1; next[0] = -1; while (i < p_len - 1) { if (j == -1 || P[i] == P[j]) { i++; j++; next[i] = j; } else j = next[j]; } } /* 在 S 中找到 P 第一次出现的位置 */ int KMP(string S, string P, int next[]) { GetNext(P, next); int i = 0; // S 的下标 int j = 0; // P 的下标 int s_len = S.size(); int p_len = P.size(); while (i < s_len && j < p_len) { if (j == -1 || S[i] == P[j]) // P 的第一个字符不匹配或 S[i] == P[j] { i++; j++; } else j = next[j]; // 当前字符匹配失败

KMP算法计算next值和nextVal值

久未见 提交于 2019-12-01 08:08:26
KMP算法: 给定一个主串S及一个模式串P,判断模式串是否为主串的子串;若是,返回匹配的第一个元素的位置(序号从1开始),否则返回0; 这里先不写算法,仅仅计算next和nextVal值 那么计算时只用到子串,也就是模式串 这里模式串为: abaabcac 第一步将模式串写上序号,我们这里从1开始(有的从0开始,建议充1开始) 然后计算出maxL值,列出从第一个开始的子串,找出相等的前缀和后缀的个数 如果2>看不懂的话,看3>, 2>计算maxL值 所以maxL值 如果这个看不懂的话, 看下面的3> 3>, 如果2>看懂了这个就不用看了 依次类推 4>计算next值 接下来将maxL复制一行,去掉最后一个数,在开头添加一个-1,向右平移一个格,然后每个值在加1的到next值 5>计算nextVal值,首先将第一个为0,然后看next和maxL是否相等(先计算不相等的) 当next和maxL不相等时,将next的值填入 当next和maxL相等时,填入对应序号为next值得nextVal值 所以整个nextVal值为: 来源: https://www.cnblogs.com/xiaokang01/p/11593513.html

HASH处理KMP算法

余生颓废 提交于 2019-12-01 07:28:55
模拟赛当天,YZR大佬告诉我可以用HASH来做KMP,然后当场没做出来,今天正好没事干,打了个HASH试试看,结果真把KMP的题给过了 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int Bas = 131, M = 1e6 + 10; 6 char a[M],b[M]; 7 long long la,lb; 8 long long sumv[M],mil[M],key; 9 long long get(long long l,long long r) 10 { 11 return sumv[r]-sumv[l]*mil[la]; 12 } 13 int main() 14 { 15 key=0; 16 memset(sumv,0,sizeof sumv); 17 scanf("%s%s",b+1,a+1); 18 la=strlen(a+1),lb=strlen(b+1),mil[0]=1; 19 for (int i=1;i<=la;++i) key=key*Bas+(int)a[i]; 20 for (int i=1;i<=lb;++i) 21 sumv[i]=sumv[i-1]*Bas+(int)b[i],mil[i]

KMP 学习笔记

好久不见. 提交于 2019-12-01 02:28:44
注意:本文面向对KMP有了解但对next数组不大清楚的人!!萌新请先了解基础!! (其实 花姐的题解 讲的特别清楚了 但是我理解的方法有点不同所以还是交题解了QWQ ) 我自己看蓝书(刘汝佳的训练指南)学了下KMP,然而蓝书也没有细讲,只是让我们查百度并且贴上了代码(其实应该是可以理解的但是我太菜了),找百度看了四个博客也并没有看太懂,但是借鉴了一点思想。 所以就自己对着代码想nex的意义,然后花了2个小时码出来这个。。。代码里的注释是我为了理解(推导)而敲出来的如果看不懂可以私信我。 因为我刚学KMP的时候感受到了绝望。。。所以希望能对同样遇到困难得人有所帮助。 ps:注释中的 \((a...b)=(c...d)\) 表示 \(T[a] = P[c],\) \(T[a+1] = P[c+1],\) \(.\) \(.\) \(.\) \(T[b-1] = P[d-1],\) \(T[b] = P[d].\) (在 \(getfail\) 中T就是P) #include <iostream> #include <cstdio> #include <cstring> //其实只是为了用strlen而已 using namespace std; #define reg register const int N = 1e6+5, INF = 1e9; char T[N], P[N];

831. KMP字符串

落花浮王杯 提交于 2019-12-01 01:13:25
给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。 模板串P在模式串S中多次作为子串出现。 求出模板串P在模式串S中所有出现的位置的起始下标。 输入格式 第一行输入整数N,表示字符串P的长度。 第二行输入字符串P。 第三行输入整数M,表示字符串S的长度。 第四行输入字符串M。 输出格式 共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。 数据范围 1 ≤ N ≤ 10 4 1≤N≤104 1 ≤ M ≤ 10 5 1≤M≤105 输入样例: 3 aba 5 ababa 输出样例: 0 2 #include<iostream> using namespace std; const int N = 1e4 + 10,M = 1e5 + 10; //p是我们的模板串,s是我们的模式串 char p[N],s[M]; int n,m; //next数组 int ne[N]; int main(){ cin >> n >> p + 1 >> m >> s + 1; //i从2开始因为next[1] = 0,就是如果第一个字母失败了就从0开始所以next[1]不用算,i直接从2开始 for(int i = 2,j = 0;i <= n;i++){ //j有退路并且i 和 j+1不匹配, while(j && p[i] != p[j +