KMP的理解与模板

                  KMP

T串主串 P串模式串

i

T串:A  B  C  A  B  C  D  H  I  J  K

P串:      A  B  C  E

j

保持i指针不回溯,通过修改j指针,让模式串尽量地移动到有效的位置

接下来我们自己来发现j的移动规律:

如图:C和D不匹配了,我们要把j移动到哪?显然是第1位。为什么?因为前面有一个A相同啊:

如下图也是一样的情况:

可以把j指针移动到第2位,因为前面有两个字母是一样的:

当匹配失败时,j要移动到下一个位置k。(模式串)存在着这样的性质:最前面的k个字符和j之前的最后k个字符是一样的。

P[0~k-1] ==P[j-k~j-1]

比如: a b c d a b c  
i == : 0 1 2 3 4 5 6  7
next:-1 0 0 0 0 1 2  3

void get_next() //初始化next数组 lenp为p数组的长度

{

int i,j;

Next[0] = j = -1;

i = 0;

while(i<lenp)  //最后一位的判断其实是多余的

{

while(j!=-1&&p[j]!=p[i])

j = Next[j];

Next[++i] = ++j;

}

}

-----------------------------------------------------------------------------------------------------------------------

Kmp部分:

i:       0 1 2 3 4 5 6 7 8 9

T串:    a b c e a b p a b c

P串:    a b c d a b c

Next[]:  -1 0 0 0 0 1 2

当i=3处,j= 3 ,t[i]!=p[j],j的指针返回到next[3] 即 j = 0

i:       0 1 2 3 4 5 6 7 8 9

T串:    a b c d a b p a b c

P串:    a b c d a b c

Next[]:  -1 0 0 0 0 1 2

若一直匹配至i=6;

j= 6,t[i]!=p[j],j返回到next[6]  移动j指针 即j=2

int kmp1()  //在t串找p串  返回下标

{

int i,j;

i = j = 0; //两个下标指针 i为主串的指针 j为模式串的指针

while(i<lent&&j<lenp)

{

while(j!=-1&&t[i]!=p[j])

j = Next[j];

i++;

j++;

}

if(j==lenp)

return i-j; //若找到返回开始下标(从0开始)

return -1;   //找不到返回-1

}

t[]  aaaaaa

p[]  aa

返回的ans = 5

int kmp2() //返回匹配次数

{

int i,j;

i = j = 0;

int ans = 0;

while(i<lent)

{

while(j!=-1&&t[i]!=p[j])

j = Next[j];

if(j==lenp-1)

{

ans++;

j = Next[j];

}

i++;

j++;

}

return ans;

}

t[] aaaaaaa

p[] aaa

返回的ans = 2

int kmp3() //返回t串中有多少个p串

{

int i,j;

i = j = 0;

int ans = 0;

while(i<lent)

{

while(j!=-1&&t[i]!=p[j])

j = Next[j];

if(j==lenp-1)

{

ans++;

j = -1;    // j指针改变为-1 然后++ 从0重新查找

}

i++;

j++;

}

return ans;

}

@一些KMP的模板题目(用上面的模板做的)

剪花布条 https://www.cnblogs.com/hao-tian/p/9643905.html         (用到了模板中的kmp3函数)

学习中。。有错误请指正  谢谢

原文地址:https://www.cnblogs.com/hao-tian/p/9643885.html

时间: 2024-08-30 15:19:19

KMP的理解与模板的相关文章

递归,回溯,DFS,BFS的理解和模板【摘】

递归:就是出现这种情况的代码: (或者说是用到了栈) 解答树角度:在dfs遍历一棵解答树 优点:结构简洁缺点:效率低,可能栈溢出 递归的一般结构: 1 void f() { 2 if(符合边界条件) { 3 /////// 4 return; 5 } 6 7 //某种形式的调用 8 f(); 9 } 回溯:递归的一种,或者说是通过递归这种代码结构来实现回溯这个目的.回溯法可以被认为是一个有过剪枝的DFS过程.解答树角度:带回溯的dfs遍历一棵解答树回溯的一般结构: 1 void dfs(int

C++--模板的概念和意义、深入理解函数模板、类模板的概念和意义

一.模板的概念与意义 Q:C++中有几种交换变量的方法?定义宏代码与定义函数A.定义宏代码优点:代码复用,适合所有的类型缺点:编译器不知道宏的存在,缺少类型检查B.定义函数优点:真正的函数调用,编译器对类型进行检查缺点:根据类型重复定义函数,无法代码复用 C.泛型编程--不考虑具体数据类型的编程方式Swap泛型写法中的T不是一个具体的数据类型,而是泛指任意的数据类型C++中的泛型编程函数模板--一种特殊的函数可用不同类型进行调用,看起来和普通函数很相似,区别是类型可被参数化函数模板的语法规则1.

KMP算法自我理解 和 模板

字符串   abcd abc abcd abc 匹配串   cdabcd 匹配串的 next  0 0 0 0 1 2: 开始匹配 abcd abc abcd abc cd abc d a,d 匹配失败 next 数组进行移动 abcd abc abcd abcd c dabcd 再次匹配 模板 #include<bits/stdc++.h> using namespace std; const int maxn=1e5+10; int nt[1000]; // next 数组首位为 0 in

第57课 深入理解函数模板

1. 函数模板深入理解 (1)编译器从函数模板通过具体类型产生不同的函数 (2)编译器会对函数模板进行两次编译 ①对模板代码本身进行编译 ②对参数替换后的代码进行编译(编译时机:可能发生在定义对象或函数调用时) (3)注意事项 ①函数模板本身不允许隐式类型转换 ②自动推导类型时,必须严格匹配 ③显式类型指定时,能够进行隐式类型转换 [编程实验]函数模板的本质 #include <iostream> #include <string> using namespace std; cla

KMP算法理解

字符串匹配算法之KMP算法一直以来都很难理解,虽然知道要减少不必要的匹配,但是仍然不懂里面的思想,即使看着代码.后来看到(2)中博客中的解释才清晰了许多,不至于在什么DFA,前缀表,部分匹配表等概念中迷失自己.主要的指导思想在于当发生不匹配的时候如何更有效的利用现在已经匹配的字符串的信息来加速移动过程,部分匹配表的存在正是挖掘一个字符串中前缀和后缀中最长公共串,比如ABCABCD,在匹配'D'时失败,考察字符"ABCABC",得到pmt['ABCABC']=3,所以外围循环索引直接前进

KMP算法理解与next数组的实现

昨天在看KMP算法,觉得很多资料写的不太容易理解 自己整理了一份,欢迎讨论([email protected]) 因为是手机码的字 直接转成了图片,有点长啊...

【luogu P3375 KMP字符串匹配】 模板

题目链接:https://www.luogu.org/problemnew/show/P3375 实际上KMP是一种自己匹配自己的模式.好好理解qaq #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1000001; char a[maxn], b[maxn]; int nex

理解VueJs模板

1.通过创建这个新的Vue实例,注意,虽然没有把它存入一个变量内,但Vue实例还是被创建了.2.通过创建这个Vue实例,我们就建立了这一联系.Vue基于上面的HTML代码,创建了一个模板,要特别注意理解的是,Vue在运行时,并不直接使用我们写的HTML代码,实际运行的网页里面也没有我们写的这些命令,Vue根据HTML代码创建的模板存储在内部,然后用这个模板,创建真正渲染成DOM的HTML代码,理解这一机制很重要.因为它让我们可以这样使用模板,和其它我们在这门课程里面将要讲的东西一样,我们写的HT

理解 JINJA 模板

UNDERSTANDING JINJA jinja是sls文件是默认的模板语言 JINJA IN STATES 在state文件被运行之前需要将文件中jinja模板语言部分处理掉,处理完之后再转化成YAML格式,最后变成python数据结构.jinja模板语法通常被用于在state文件中使用控制结构,如if条件,for循环等,可以达到消除冗余数据的效果. 在sls文件中使用jinja模板示例: 1 {% if grains['os'] != 'FreeBSD' %} 2 tcsh: 3 pkg: