kmp算法

KMP算法--待定

故事扮演 提交于 2019-12-10 02:36:37
https://blog.csdn.net/slimmm/article/details/83989811 KMP算法 准备搞压缩看他文章 不清楚干啥的 先放着这 #include <stdio.h> #include <string.h>//memset #include <stdlib.h>//free #include <stddef.h> #define uint8_t unsigned char #define uint16_t unsigned short #define uint32_t unsigned int #define uint64_t unsigned long long #define uLong unsigned long typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; #define TEST_STR 0 //选择测试对象是字符串还是数组 typedef struct KMP { uchar *src; //源数据 uchar *dst; //要求匹配的数据 ushort sLen; //源数据长度 ushort pLen; //匹配数据长度 ushort coord; //匹配到数据记录其坐标 ushort matchLen

面试常规算法复习kmp

送分小仙女□ 提交于 2019-12-06 14:34:06
1.核心是求next数组 2.考虑两种情况: -当p[j] == p[k]时,当前的next等于上一个next加一 -当p[j] != p[k]时 package com.company; import java.util.Scanner; public class kmp { public static void main(String[] args) { Scanner in = new Scanner(System.in); String str1 = in.next(); String str2 = in.next(); int[] next = getNext(str2.toCharArray()); getkmp(str1.toCharArray(), str2.toCharArray(), next); } public static int[] getNext(char str[]){ int[] next = new int[1005]; int n = str.length; next[0] = -1; int k = -1; int j = 0; while (j < n){ if (k == -1 || str[k] == str[j]){ k++; j++; next[j] = k; } else{ k = next[k]; } } for(int i =

模板 - 字符串 - KMP算法

一世执手 提交于 2019-12-05 04:07:56
int pi[1005]; void GetPrefixFunction(char *s, int sl) { pi[0] = 0, pi[1] = 0; for(int i = 1, k = 0; i < sl; ++i) { while(k && s[i] != s[k]) k = pi[k]; pi[i + 1] = (s[i] == s[k]) ? ++k : 0; } } //返回t在s中所有occurrence的首地址,s和t都是从0开始的 int ans[1005], atop; void KMP(char *s, int sl, char *t, int tl) { GetPrefixFunction(t, tl); atop = 0; for(int i = 0, k = 0; i < sl; ++i) { while(k && s[i] != t[k]) k = pi[k]; k += (s[i] == t[k]); if(k == tl) ans[++atop] = i - tl + 1; } } 来源: https://www.cnblogs.com/KisekiPurin2019/p/11904828.html

KMP算法

空扰寡人 提交于 2019-12-04 21:37:17
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 void getnext(char a[],int next[]){ 6 int n = strlen(a); 7 int i=0,j=-1; 8 next[0] = -1; 9 while(i < n){//n是数组a有效数据的长度 10 if(j==-1 || a[i]==a[j]){//j==-1一方面使得i=0,j=-1时进入next赋值语句使得next[1]=0 11 next[++i]=++j; 12 } 13 else j = next[j]; 14 } 15 } 16 void NewGetNext(char p[],int next[]){//改进版求next数组方法 17 int n = strlen(p); 18 int i=0,j=-1; 19 next[0] = -1; 20 while(i < n){//n是数组a有效数据的长度 21 if(j==-1 || p[i]==p[j]){ 22 // next[++i]=++j;未改进的 23 i++,j++; 24 //改进后的: 25 if(p[j] != p[i]) 26 next[i]=j; 27 else//如果p[j]==p[i],那么直接next[i]

KMP

风流意气都作罢 提交于 2019-12-04 16:39:08
字符串匹配算法 针对被匹配字段生产一个部分匹配表 A B C D A B D 0 0 0 0 1 2 0 部分匹配表 熟悉前缀与后缀的概念 ,“部分匹配表” 的生产就是根据前缀、后缀的最苍的共有元素的长度 前缀:除去最后一个字符外,一个字符串的全部头部组合【{A},{AB},{ABC},{ABCD},{ABCDA},{ABCDAB}】 后缀: 除了第一个字符串外。一个字符串的全部尾部组合 【{D},{BD},{ABD},{}】 我们会针对A B C D A B D 中 {A,AB,ABC,ABCD,ABCDA,ABCDAB,ABCDABD}以前进行前前后缀的处理,然后比对前后缀中 ,相同的字符 ,并在对应的位置标记相同的个数,形成部分匹配表 来源: https://my.oschina.net/u/198077/blog/3130441

【模板】KMP

只谈情不闲聊 提交于 2019-12-04 11:52:24
(比赛前最后的挣扎) KMP是什么 高效的字符串匹配算法。可以用于查找字符串s中是否含有模式串p。 (剩下的简介自行百度) 思路与实现 万物先从暴力开始 怎样用暴力求出s串中是否含有p串?若含有请输出第一次出现的位置。 暴力就好 比对s[i]是否等于p[j],若等则继续,若不等就让i回到i-j+1位置,j=0继续比对。 这个画个图就很好懂(因为它真的太暴力了) 此时i=j=3 s[i]与p[j]不适配 所以i回到i-j+1 j=0 一直循环直至找到或者i=slen 这个过程一看就十分暴力,怎么优化呢? 观察下图: 其实可以不用移动i,通过移动j来不断比对。 因为ABA中第0位A与第2位A相等,而此时对于S与P的前三个字符又是完全适配的。 所以可以像下图一样移动: 这样就可以节省不少时间。 所以得出 大概思路: 先预处理出对于p中任意一个p[i],若不适配,应该向前移动到next[i]的位置,从而实现。 而对于任意next[j]=k,j表示最大真后缀的结束位置,k表示最大真前缀的结束位置。 举个栗子: 看懂了吗? 不需要知道为什么只需要知道这个东西是啥就行。 为什么一会就知道了hh 好的这究竟是为什么呢? 对于上述模式串: 取第二个A分析,对于该模式串的一个子串 A B C D A 含有最长真前缀 A 和最长真后缀 A 所以对于位置 5 (也就是字符A)next[5]

KMP算法简介

百般思念 提交于 2019-12-04 09:30:30
KMP算法 大意 大串a中找小串b 小串处理 \(next[i]\) 表示 \(b[i]\) 匹配过程中失配情况下可以向前跳几个字符,意思就是b的前i个的公共前后缀的最大长度 如 \(B="ABCBCABCD",i=7\) 时 \(next[i]\) 为 \(3\) 。 处理:如果 \(b[next[x-1]]==b[x]\) ,则 \(next[x]=next[x-1]+1\) ,否则在 \(x-1\) 的公共前后缀中找,迭代这一过程 \(query(x,y)=\{^{\ next[x-1]+1\ \ \ (b[next[x-1]]==y)}_{\ query(next[x-1],y)\ \ \ (b[next[x-1]]!=y)}\) \(next[i]=query(i,b[i])\) 可以用 \(while\) 实现 大串处理 若现在找到大串的 \(p1\) 位置与小串的 \(p2\) 位置而失配,那么接下来找 \(b[next[p2]+1]\) 是否等于a[p1],如果依然不等于,就在next[p2]+1里面继续找 相当于每次讲 \(p2\) 迭代为 \(next[p2]\) 代码 #include<bits/stdc++.h> using namespace std; int next[1000010]; char a[1000010],b[1000010]; int

hdoj2594(kmp算法next数组的应用)

筅森魡賤 提交于 2019-12-03 13:38:17
题目链接:https://vjudge.net/problem/HDU-2594 题意:给定两个字符串s1、s2,求s1的前缀和s2的后缀的最长公共部分。 思路:   将s1和s2连接后求nex数组即可,当公共部分超过s1、s2长度的最小值时,输出最小值。 AC代码: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1e5+5; int len1,len2,len,Min,nex[maxn],ans; char s1[maxn],s2[maxn]; void get_next(){ int j; j=nex[0]=-1; for(int i=1;i<len;++i){ while(j>-1&&s1[i]!=s1[j+1]) j=nex[j]; if(s1[i]==s1[j+1]) ++j; nex[i]=j; } } int main(){ while(~scanf("%s%s",s1,s2)){ len1=strlen(s1); len2=strlen(s2); Min=min(len1,len2); strcat(s1,s2); len=len1+len2; get_next(); if(nex[len-1]+1>Min) ans=Min;

POJ3080 Blue Jeans 题解 KMP算法

痞子三分冷 提交于 2019-12-03 11:42:12
题目链接: http://poj.org/problem?id=3080 题目大意:给你N个长度为60的字符串(N<=10),求他们的最长公共子串(长度>=3)。 题目分析:KMP字符串匹配基础题。直接枚举第1个字符串的所有子串,判断这个子串是否出现在另外N-1个串中。 实现代码如下: #include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> using namespace std; const int maxn = 66; int n, m, nxt[maxn]; string s, t; // s代表母串,t代表子串 int T, N; string ss[11]; vector<string> tt; void cal_next() { m = t.length(); for (int i = 0, j = -1; i < m; i ++) { while (j != -1 && t[j+1] != t[i]) j = nxt[j]; nxt[i] = (j+1 < i && t[j+1] == t[i]) ? ++j : -1; } } bool check_s_has_t() { n = s.length(); // cal_next();

POJ2185 Milking Grid 题解 KMP算法

余生颓废 提交于 2019-12-03 11:41:36
题目链接: http://poj.org/problem?id=2185 题目大意:求一个二维的字符串矩阵的最小覆盖子矩阵,即这个最小覆盖子矩阵在二维空间上不断翻倍后能覆盖原始矩阵。 题目分析:next函数的应用。需要枚举每一行每一列的字符串所对应的的 \(nxt[]\) 值,然后通过分析计算出最小的宽和最小的高。 具体分析 参考链接: https://blog.csdn.net/u013686535/article/details/52197467 一看这题,容易想出一种很直观的做法:求出每一行的最小重复串长度,取所有行的最小重复串长度的lcm为宽;对列也同样操作求出高。这种想法虽然很直观,但是否正确呢? 事实上,这种算法并不是正确的。如下面的这个反例: 2 8 ABCDEFAB AAAABAAA 对于这个例子:第一行为6,第二行为5,6与5的最小公倍数为30,大于8则取8为宽,但明显是错误的。 但由于poj的测试数据太弱,以致使用这种方法的程序也可以通过。 下面介绍一下正解的做法。 首先是确定宽度:我们分别求出每行所有可能的重复子串长度,例如对于aaaa就有1、2、3和4,然后取每行都有的重复子串长度中最小的作为宽。 例如,对于上面的例子,第一行的重复子串长度只可能是6或8(显然整个串为一个重复子串也是可以的),第二行则可能是5、6、7或8,那么取它们都有的6和8当中最小值6