(原文有详解,若点击链接跳转失败,直接在浏览器输入 bestsort.cn 即可) 从多个字符串中查找是否有某个字符串
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include <queue> #include <cstdlib> #include <cmath> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 2*1e6+9;
int trie[maxn][26]; int cntword[maxn]; int fail[maxn]; int cnt = 0;
void insertWords(string s){ int root = 0; for(int i=0;i<s.size();i++){ int next = s[i] - 'a'; if(!trie[root][next]) trie[root][next] = ++cnt; root = trie[root][next]; } cntword[root]++; } void getFail(){ queue <int>q; for(int i=0;i<26;i++){ if(trie[0][i]){ fail[trie[0][i]] = 0; q.push(trie[0][i]); } }
while(!q.empty()){ int now = q.front(); q.pop(); for(int i=0;i<26;i++){ if(trie[now][i]){
fail[trie[now][i]] = trie[fail[now]][i]; q.push(trie[now][i]); } else trie[now][i] = trie[fail[now]][i]; } } } int query(string s){ int now = 0,ans = 0; for(int i=0;i<s.size();i++){ now = trie[now][s[i]-'a']; for(int j=now;j && cntword[j]!=-1;j=fail[j]){ ans += cntword[j]; cntword[j] = -1; } } return ans; } int main() { int n; string s; cin >> n; for(int i=0;i<n;i++){ cin >> s ; insertWords(s); } fail[0] = 0; getFail(); cin >> s ; cout << query(s) << endl; return 0; }
|