字符串类模板及总结(随缘更新)

昨晚与集训队的诸位聚餐,得悉弘毅的选拔比预想中要近,而且英语入学考也会与是否大一能参加四级考有关。结束后,第一次来到武大ACM训练室,被一桌论文、草稿、书籍、KFC、外卖袋、电脑、可乐瓶……的混沌空间深深震撼。黑暗的夜幕下,机房灯火闪烁,两个大三巨佬与一个大一萌新,就这样整整齐齐地坐成一排,玩起了音游……返程时,我白嫖了亿本本资料书,md晚上聚餐花了200多还没饱也算不枉此行吧:)
武大还是很大,这个世界很大;可往日的一切让我明白,一切初见的广博都会在有一天变得渺小,武大也会渺小,个人也会渺小

  • \(kmp\)
    神秘の\(DFA\)
luoguP3375【模板】KMP字符串匹配
# include "bits/stdc++.h"
using namespace std;
constexpr int N = 1e6 + 3;
char txt[N + 1], pat[N + 1];
int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//	cin >> (txt + 1) >> (pat + 1); // in luogu, this sentence will lead to RE
	scanf("%s%s", txt + 1, pat + 1); // for convenience and to prevent the array from going out of bounds, the srings subscript starts at 1
	int len_1 = strlen(txt + 1), len_2 = strlen(pat + 1);
	vector<int> nxt(len_1 + 1);
	int j = 0;
	for(int i = 2; i <= len_2; ++i) { // the pattern string will be matched by itself to obtain the nxt array that conveniently makes the prefix and suffix the same
		while(j && pat[i] != pat[j + 1]) j = nxt[j]; // seek forward for j with the same prefix
		if(pat[i] == pat[j + 1]) ++j;
		nxt[i] = j; // hwo should i jump after i + 1 mismatch
	}
	j = 0; // j can be viewed as the position of the last place of the pattern string that has currently been matched
	for(int i = 1; i <= len_1; ++i) {
		while(j && txt[i] != pat[j + 1]) j = nxt[j]; // if it fails in matching, it keeps jumping back until it can match again
		if(txt[i] == pat[j + 1]) ++j; // if the match is successful, the corresponding pattern string position is advanced one place
		if(j == len_2) {
			printf("%d\n", i - j  + 1);
			j = nxt[j];
		}
	}
	
	for(int i = 1; i <= len_2; ++i) printf("%d ", nxt[i]);
	return 0;
}

image


  • AC自动机
luoguP3808【模板】AC自动机(简单版)
# include "bits/stdc++.h"
using namespace std;
constexpr int N = 1e6 + 3;
struct aho_corasic_automation {
	int ch[N][26], tot[N], fail[N], trie_index;
	void insert(char *str) {
		int len = strlen(str + 1), u = 0;
		for(int i = 1; i <= len; ++i) {
			int v = str[i] - 'a';
			if(!ch[u][v]) ch[u][v] = ++trie_index;
			u = ch[u][v];
		}
		++tot[u];
	}
	
	void build() {
		queue<int> q;
		for(int i = 0; i < 26; ++i) {
			if(ch[0][i]) {
				q.push(ch[0][i]);
			}
		}
		while(!q.empty()) {
			int u = q.front();
			q.pop();
			for(int i = 0; i < 26; ++i) {
				if(ch[u][i]) {
					fail[ch[u][i]] = ch[fail[u]][i];
					q.push(ch[u][i]);
				}
				else {
					ch[u][i] = ch[fail[u]][i];
				}
			}
		}
	}
	
	int query(char *str) {
		int len = strlen(str + 1), u = 0, ans = 0;
		for(int i = 1; i <= len; ++i) {
			u = ch[u][str[i] - 'a'];
			for(int v = u; v && ~tot[v]; v = fail[v]) {
				ans += tot[v];
				tot[v] = -1;
			}
		}
		return ans;
	}
} AC;
char str[N];
int main() {
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i) {
		scanf("%s", str + 1);
		AC.insert(str);
	}
	AC.build();
	scanf("%s", str + 1);
	printf("%d\n", AC.query(str));
	return 0;
}

image

posted @ 2022-08-18 13:36  邱涵的秘密基地  阅读(40)  评论(0编辑  收藏  举报