WHCSRL 技术网

KMP与题目练习

最长相等前后缀是决定我们移位的关键

而且next数组的数值只与子串本身有关。
所以next[i]=j,含义是:下标为i 的字符前的字符串最长相等前后缀的长度为j。
练手写法

#include<iostream>
using namespace std;
int ne[1000010];
typedef struct{
	char data[100010];
	int length;
}Sstring; //串的数据结构
//Sstring 是串的数据结构
//typedef重命名结构体变量,可以用Sstring t 定义一个结构体。
Sstring s,t;
void Getnext(){
	int j = 0,k = -1;
	ne[0] = -1; //一定要设置初值!!
	while(j < t.length-1){
		if(k=-1||t.data[j]==t.data[k]){
			ne[++j] = ++k; //最后一次进来的时候 j= t.length -2  出去就变为了 length-1了 
		}else k = ne[k]; //前缀的前缀 
	}
}
int KMPget(){
	int i = 0,j = 0;
	Getnext();
	while(i < s.length&&j<t.length){
		if(j==-1||s.data [i]==t.data [j]){ //相等就双指针 往前移  也有可能从头开始匹配
			i++;j++;
		}else j = ne[j];	
	}
	if(j>=t.length) {
		return i- t.length; //这里的i已经是length了所以可以直接减去t.length
	}else return -1;	
} 
int main(){
	int n,m;
	cin>>m>>t.data>>n>>s.data;
	s.length = n;
	t.length = m;
	int ans = KMPget();
	cout<<ans<<endl;
	return 0;
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

主要要注意的地方是这个unsigned,比如在KMP的C++实现中如果用了string的话,就会有负数和size_t比较的情况,这个时候就会出现很奇怪的结果

同样的错误
如:

#include <bits/stdc++.h>
using namespace std;

int main(void)
{   
    vector<int> v;
    v.push_back(1);
    unsigned int a=-1;
    cout<<a<<endl;
    cout<<(-1>=v.size())<<endl;
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

解释原因
(vector.size()的一些常见错误总结)

推荐阅读