字符串类模板及总结(随缘更新)
昨晚与集训队的诸位聚餐,得悉弘毅的选拔比预想中要近,而且英语入学考也会与是否大一能参加四级考有关。结束后,第一次来到武大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;
}
- 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;
}