kmp板子

书上讲的感觉不好理解,不如算法竞赛上分析的

题目链接:
https://www.luogu.com.cn/problem/P3375
贴板子:

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;


const int N = 1e6 + 5;
string tar, p;
int Next[N];
queue<int>qid;

void getNext()
{
	Next[0] = Next[1] = 0;
	for (int i = 1; i < p.length(); i++)
	{
		int j = Next[i];
		while (j and p[i] != p[j])j = Next[j];//回退
		if (p[j] == p[i])Next[i + 1] = j + 1;//修改i+1等于j+1(指向的位置)
		else Next[j + 1] = 0;//回退到id=0
	}
}
void kmp()
{
	getNext();//预处理Next数组
	int j = 0;
	for (int i = 0; i < tar.length(); i++)
	{
		while (j and tar[i] != p[j])j = Next[j];
		if (tar[i] == p[j])j++;
		if (j == p.length()) { qid.push(i - p.length() + 1 + 1); j = Next[j ]; }//qid的push这里要注意下就行,根据题目来
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> tar >> p;
	kmp();
	while (!qid.empty())
	{
		cout << qid.front() << endl;
		qid.pop();
	}
	for (int i = 1; i < p.length(); i++)cout << Next[i] << ' ';
	cout << Next[p.length()];
	return 0;
}

posted on 2024-04-02 12:16  WHUStar  阅读(4)  评论(0编辑  收藏  举报