kmp算法

kmp算法,求重复字符串

匿名 (未验证) 提交于 2019-12-03 00:15:02
不是很懂,不管了先背下来 public class Demo { public static void main(String[] args) { String s1 = "ADBCFHABESCACDABCDABCE"; String s2 = "ABCDABCE"; int i = kmp(s1, s2); System.out.println("下标 i="+i+" 对应字符串:"+s1.substring(14)); } public static int kmp(String s1, String s2) { char[] c1 = s1.toCharArray(); char[] c2 = s2.toCharArray(); int[] next=getNext(s2); int i=0,j=0; while (i < c1.length && j <c2.length) { if (j == -1 || c1[i] == c2[j]) { i++; j++; } else { j = next[j]; } } if (j == c2.length) return i - j; else return -1; } public static int[] getNext(String s) { char[] chars = s.toCharArray(); int[]

[一本通学习笔记] KMP算法

匿名 (未验证) 提交于 2019-12-03 00:12:02
KMP算法 对于串s[1..n],我们定义fail[i]表示以串s[1..i]的 最长公共真前后缀 。 我们首先考虑对于模式串p,如何计算出它的fail数组。定义fail[0]=-1。 根据“真前后缀”的条件,容易得到fail[1]=0 对于任意的i>1,显然在s[fail[i-1]+1]==s[i]的时候,我们有fail[i]=fail[i-1] 如果s[fail[i-1]+1]!=s[i],那么我们需要去尝试s[fail[fail[i-1]]+1]是否与s[i]相等,否则再继续下去。 这是因为我们最终要找的是s[1..i]的最长公共前后缀,如果它不是由s[1..i-1]的最长公共前后缀扩增而来,那么它一定是由s[1..fail[i-1]]的最长公共前后缀扩增而来。毕竟,最长公共前后缀包含了若干个公共前后缀。即s[1..fail[i-1]]的最长公共前后缀也是s[1..i-1]的一个公共前后缀,虽然它未必最长。 // Build fail array for pattern string for(int i=2;i<=m;i++) { fail[i]=fail[i-1]; while(p[fail[i]+1]-p[i] && fail[i]) fail[i]=fail[fail[i]]; if(p[fail[i]+1]==p[i]) ++fail[i]; }  fail[0]=

KMP算法

匿名 (未验证) 提交于 2019-12-02 23:53:01
前提技能: 前缀数组 参考博客: KMP算法(kuangbin) const int maxn=1e5; int Next[maxn]; /*求前缀数组*/ /*t[0]对应Next[1]*/ /*Next[0]=-1*/ void getNext(string t) { int i=0,j=-1,n=t.length(); Next[0]=-1; while(i<n) { if(j==-1||t[i]==t[j]) Next[++i]=++j; else j=Next[j]; } } /*求 t 在 s 中出现的次数(可交叉)(即:s="bababa" t="baba" KMP_count()=2)*/ int KMP_count(string s,string t) { int ans=0,slen=s.length(),tlen=t.length(); if(slen==1&&tlen==1) { if(s==t) return 1; else return 0; } getNext(t); for(int i=0,j=0;i<slen;++i) { while(j>0&&s[i]!=t[j]) j=Next[j]; if(s[i]==t[j]) j++; if(j==tlen) ans++,j=Next[j]; } return ans; } /*求 t 在 s

KMP算法

主宰稳场 提交于 2019-12-02 21:59:15
KMP算法用于字符串匹配问题 原有一个主串T和一个要匹配字符串S 对S求next熟组然后进行较少回溯匹配 求next数组。也就是在S串匹配不正确时 进行回溯。 每个next数组指向前一个应该回溯对下标 然后进行匹配 对于每个不匹配字符串重新依据next数组匹配 来源: https://www.cnblogs.com/AAAzhuo/p/11764111.html

串匹配-BF和KMP算法

▼魔方 西西 提交于 2019-12-02 05:06:41
文章目录 串匹配-BF和KMP算法 BF算法 KMP算法 求next的算法 没想到今天是1024程序员节日,先祝大家节日快乐 希望有幸看到这篇文章的大佬们学的多不秃头(-。-) 串匹配-BF和KMP算法 串模式匹配即子串查找。设s和p是给定的两个字符串,在主串s中查找子串p的过程,成为模式匹配。如果在s中找到等于p的字串,则称匹配成功,函数返回p在s中首次出现的位置或序号,否则匹配失败,返回-1,p也称为模式串。 BF算法 解决这个问题,有两种算法,相对简单一种的叫做BF算法也叫简单匹配算法 BF算法的总体思路就是首先将s0与p0比较,若不相同,就将s1与p0比较,依次下去,直到si与p0相同,然后再比较之后的字符,就是将s(i+1)与p1比较,依次下去,若p比较到末尾,则匹配成功,若其中有一个字符不相等,则s回到本趟开始的一个字符位置,即s(i-j+1),继续下一趟的比较。 时间复杂度最好是O(n+m),最差为O(n*m) 代码如下: public static int KM(char[] s, char[] p){ int i = 0; int j = 0; while(i < s.length && j < p.length){ if (s[i] == p[j]){ i++; j++; } else { i = i-j+1; j = 0; } if (j > p.length

字符串模式匹配——KMP算法

核能气质少年 提交于 2019-12-01 16:53:10
KMP算法匹配字符串 朴素匹配算法   字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就重新去从父串的下一个字符开始匹配,这样的算法虽然理解起来容易,但是算法的时间复杂度无疑是很高的,假如父串是一个很长的字符串,而字串恰恰不和父串匹配,那无疑是对CPU的迫害。   下面贴几张图看看这种朴素匹配算法: 但是第四个出现失配,就得重新让字串去和父串的第二个字符匹配,发现第二个也不匹配,只能再次匹配第三个,如下:   这样下来时间复杂度大大变高,但是通过上帝视角我们可以发现其实第二个完全不用试,但是计算机不知道啊,所以我们就需要一个更好的算法来解决这个问题,这个算法就是要在朴素算法的基础上额外告诉计算机哪些地方不用尝试,可能我上面的这个例子举得不太恰当,但是这个算法的额外功能就是告诉了计算机如果某个位置失配了应该去尝试哪个位置。    KMP算法——和计算机的友好交流   前面我们说KMP算法其实就是告诉计算机如果某个位置失配后应该往哪个位置回溯。而这个功能的实现其实只需要一个next数组,而这个数组也恰恰是这个算法的核心所在。 next数组   这个数组里面存储的就是字串中每个位置失配后应该回溯的下标。举个例子,比如第9个元素失配后应该回溯到第3个再次匹配尝试

KMP(模板)

老子叫甜甜 提交于 2019-12-01 13:32:32
kmp算法是解决单模匹配问题的算法,难点在于求next[]数组 求next[]数组:对于模板串的所有前缀子串的最长公共前后缀的长度,就是next[]数组的值 eg:主串为cbbbaababac 子串为ababac 初始化next[0]=-1; 子串的最长公共前后缀长度 a -->0 next[1]=0 ab -->0 next[2]=0 aba -->1 next[3]=1 abab -->2 next[4]=2 ababa -->3 next[5]=3 next[]数组的作用是在当子串在和模板串失配的时候,next[]数组提供下一个字串的字母,和当前位置的模板串字母匹配 eg:模板串是cbbbaababac,子串是ababa 子串下标: 0 1 2 3 4 a b a b a 失配跳转位置next[]:-1 0 0 1 2 这里解释一下:当子串和模板串失配的时候,就根据next[]的值移动子串到相应位置去和模板串匹配。 这里模拟一下匹配过程,i表示模板串的当前匹配位置,j表示子串的当前匹配位置,初始i=0,j=0;模板串p[],子串s[] a!=c ---> i++ i=1,j=0 a!=b ---> i++ i=2,j=0 a!=b ---> i++ i=3,j=0 a!=b ---> i++ i=4,j=0 a==a ---> i++,j++ i=5,j=1 b!=a ---

kmp算法,求重复字符串

一个人想着一个人 提交于 2019-12-01 11:50:34
不是很懂,不管了先背下来 public class Demo { public static void main(String[] args) { String s1 = "ADBCFHABESCACDABCDABCE"; String s2 = "ABCDABCE"; int i = kmp(s1, s2); System.out.println("下标 i="+i+" 对应字符串:"+s1.substring(14)); } public static int kmp(String s1, String s2) { char[] c1 = s1.toCharArray(); char[] c2 = s2.toCharArray(); int[] next=getNext(s2); int i=0,j=0; while (i < c1.length && j <c2.length) { if (j == -1 || c1[i] == c2[j]) { i++; j++; } else { j = next[j]; } } if (j == c2.length) return i - j; else return -1; } public static int[] getNext(String s) { char[] chars = s.toCharArray(); int[]

详讲KMP算法

∥☆過路亽.° 提交于 2019-12-01 07:01:17
两个字符串:     模式串:ababcaba     文本串:ababcabcbababcabacaba KMP算法作用:快速在文本串中匹配到模式串 如果是穷举法的方式: 大家有发现,这样比效率很低的。 所以就需要使用一种高效率模式的算法:KMP算法。 大家有看到上面的穷举法,是一位一位的挪。那可以一次挪多位不就行了。像下面: 那么为什么可以这样挪呢? 模式串向右移动的距离 = 已匹配字符数 - 失配字符的上一位字符所对应的最大长度值 那么我们要怎么找出每位上的最大长度值呢呢? 我们来找一下。 所以,使用KMP算法进行挪位: 来源: https://www.cnblogs.com/qzhc/p/11665886.html

kmp算法模板

僤鯓⒐⒋嵵緔 提交于 2019-11-30 19:10:49
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 100000; int nextval[maxn]; void get_next(char* T) { int i = 1, j = 0; nextval[1] = 0; int len = strlen(T+1); while(i < len) { if(j == 0 || T[i] == T[j]) { ++i; ++j; if(T[i] == T[j]) nextval[i] = nextval[j]; else nextval[i] = j; } else j = nextval[j]; } } int kmp(char* T, char* S) { int lent = strlen(T+1), lens = strlen(S+1); int i = 1, j = 1; while(i <= lens && j <= lent) { if(j == 0 || S[i] == T[j]) { ++i; ++j; } else j = nextval[j]; } if(j > lent) return i - lent; return 0; } int main() { freopen(