P3375 【模板】KMP0pts玄关求助
  • 板块学术版
  • 楼主M_Jun
  • 当前回复1
  • 已保存回复1
  • 发布时间2025/1/20 15:16
  • 上次更新2025/1/20 17:47:42
查看原帖
P3375 【模板】KMP0pts玄关求助
1098953
M_Jun楼主2025/1/20 15:16

rt, link

测试点二下载数据是过的,但是WA。 代码如下

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>

using namespace std ;

typedef long long lint ;
typedef long double dint ;

const lint MAXN = 1e6 + 5 ; // Next[] 长度
const lint MAXL1 = 1e6 + 5 ; // s1 长度
const lint MAXL2 = 1e6 + 5 ; // s2 长度

lint times ;
lint t1 , t2 ; // s1, s2 遍历到的下标
string s1, s2 ; // 文本串与模板串
lint lens1, lens2 ; // 文本串与模板串的长度

vector<lint> Next ; // Next[i]:S[0…i-1] 这个前缀的前缀后缀最大值
//vector<lint> place ; // 记录模板串在文本串上的位置
vector<lint> broder ; // 记录 broder 值

// 构建模板串 s2 的 next 数组
void get_Next(vector<lint> &Next, string &s, lint lens) {
	t1 = 0 ;
	Next[0] = t2 = -1 ;
	while (t1 < lens) {
		if (t2 == -1 || s[t1] == s[t2]) // 可以扩展匹配
			Next[++ t1] = ++ t2 ; // 扩展匹配
		else // 回退 t2,查找前缀中可能的匹配
			t2 = Next[t2] ;
	}
	return ;
}

// 判断模板串 s2 是否是文本串 s1 的子串
bool Kmp(vector<lint> &Next, string &s1, string &s2,  lint &lens1, lint &lens2) {
	t1 = 0, t2 = 0 ;
	while (t1 < lens1 && t2 < lens2) {
		// 当前字符匹配 或 处于模板串 s2 的第一个字符
		if (t2 == -1 || s1[t1] == s2[t2]) 
			t1 ++ , t2 ++ ; // 移动指针
		else // t2 回退
			t2 = Next[t2] ;
	}
	if (t2 == lens2) // 找到了匹配的子串
		return true ;
	else // 没有找到匹配
		return false ;
}

// 求模板串 s2 在文本串 s1 中出现了多少次
lint KMP(vector<lint> &Next, string &s1, string &s2,  lint &lens1, lint &lens2) {
	lint times = 0 ;
	t1 = 0, t2 = 0 ;
	while (t1 < lens1) {
		// 当前字符匹配 或 处于模板串 s2 的第一个字符
		if (t2 == -1 || s1[t1] == s2[t2]) 
			t1 ++ , t2 ++ ; // 移动指针
		else  // t2 回退
			t2 = Next[t2] ;
		if (t2 == lens2) { // 匹配成功
			times ++ ;
//			place.push_back(t1 - lens2 + 1) ;
			printf("%lld\n", t1 - lens2 + 1) ;
			t2 = Next[t2] ;
		}
	}
	return times ;
}

signed main() {
	
	// vector 初始化
	Next.resize(MAXN, 0) ;
	broder.resize(MAXL2, 0) ;
	
	// 输入
	getline(cin, s1) ;
	getline(cin, s2) ;
	lens2 = s2.size() ;
	lens1 = s1.size() ;
	
	// 处理
	get_Next(Next, s2, lens2) ;
	times = KMP(Next, s1, s2, lens1, lens2) ;
//	sort(place.begin() , place.end()) ;
	
	// 输出
//	for (lint i = 0 ; i < place.size() ; i ++)
//		cout << place[i] << '\n' ;
	for (int i = 1 ; i <= lens2 ; i ++) 
		cout << Next[i] << ' ' ;
	putchar('\n') ;
	
	return 0 ;
}
2025/1/20 15:16
加载中...