KMP算法学习 & HDU 1686 Oulipo参考代码

KMP讲解推荐视频(来源于https://www.bilibili.com):

参考视频1

参考视频2


定义
真前缀:对于当前位置i,从0~k(0<=k 真后缀:对于当前位置i,从k~i(1<=k<=i)构成的子串;例如:abcd的真后缀有bcd,cd,d
最长公共真前、后缀:真前缀和真后缀相同,而且长度最长;例如:aaaa的最长公共真前、后缀为aaa,长度为3;abab的最长公共真前、后缀为ab,长度为2
next数组的含义:next[i]:存放i之前子串(0~i-1共i个字符构成)的最长公共真前、后缀的长度。


手算Next数组

对于模式串ababaabab,手算代码中getNext1中的Next数组(next1)和getNext2中的Next数组(next2)

tmp[i]:  对于下标i,存放0~ i的最长公共真前、后缀长度
next1[i]: next1[0]=-1,对于下标i,存放0~(i-1)的最长公共真前、后缀长度;若下标从1开始,则加1即可
next2[i]: next2[0]=-1,对于下标i,若next1[i]!=tmp[i]-1则为next1[i],否则为next2[ next1[i] ];若下标从1开始,则加1即可

下标 0 1 2 3 4 5 6 7 8
字符 a b a b a a b a b
tmp[i] 0 0 1 2 3 1 2 3 4
tmp[i]-1 -1 -1 0 1 2 0 1 2 3
next1[i] -1 0 0 1 2 3 1 2 3
next2[i] -1 0 -1 0 -1 3 0 -1 0

题目链接

题意:查找模式串t在主串s中出现的次数。


参考代码

//HDU 1686 查找模式串t在主串s中出现的次数,模式匹配,KMP算法
#include 
#include 
#include 
using namespace std;

string s, t; //s主串,t模式串
vector  Next; //外部数组、变量不取名为next以免编译错,类似于max,min,count不作为外部变量名
int n, m; //s主串长度n,t模式串长度m


void getNext1()  // O(m),计算Next数组的方法
{
    int i=0, j=-1;
    Next[0]=-1;

    while(i>t>>s;  //输入模式串和主串
	n=s.size(); //主串长度
	m=t.size(); //模式串长度

	//简单起见(i++后next[i]=j不用判断i下标越界),最后一个字符后的位置也计算一下next值,
    Next.resize(t.size()+1);
	getNext1();
	//Next.clear();
    //getNext2();
	int pos=-1;
    cout << KMP(pos) <

你可能感兴趣的:(ACM&Programming)