Title Link: Detect the Virus
Test instructions: N mode string, a text string, asking the text string contains several pattern strings.
Parsing: Decoding + AC automata.
Decoding process: The string is converted to ASCII and then converted to binary according to the corresponding ASCII, each is 6 bits, not enough to add 0, and then take 8 bits for a character, the string to be evaluated to be the string.
PS: note Sigma_size = 256
AC Code:
#include <bits/stdc++.h>using namespace std;struct trie{int next[520*64][256], fail[520*64], end[520*64]; int root, L; int NewNode () {for (int i = 0; i <; i++) next[l][i] = 1; end[l++] =-1; return L-1; } void Init () {L = 0; root = NewNode (); } void Insert (unsigned char buf[], int len, int id) {int now = root; for (int i = 0; i < len; i++) {if (next[now][buf[i]] = = 1) next[now][buf[i]] = NewNode (); now = next[now][Buf[i]]; } End[now] = ID; } void Build () {queue<int> Q; Fail[root] = root; for (int i = 0; i < i++) {if (next[root][i] = = 1) next[root][i] = root; else{fail[Next[root][i]] = root; Q.push (Next[root][i]); }} while (! Q.empty ()) {int now = Q.front (); Q.pop (); for (int i = 0; i < i++) { if (next[now][i] = =-1) next[now][i] = next[Fail[now]][i]; else{fail[next[now][i]] = next[Fail[now]][i]; Q.push (Next[now][i]); }}}} bool used[520]; int query (unsigned char buf[], int len, int n) {memset (used, false, sizeof (used)); int now = root; for (int i = 0; i < len; i++) {now = next[now][buf[i]]; int temp = now; while (temp! = root) {if (end[temp]! =-1) used[end[temp]] = true; temp = fail[temp]; }} int res = 0; for (int i = 0; i < n; i++) if (Used[i]) res + +; return res; }};unsigned Char buf[2050];int tot;char str[4000];unsigned Char s[4000];unsigned char Get (char ch) {if (ch >= ' A ' &am p;& ch <= ' Z ') return CH-' A '; if (Ch >= ' a ' && ch <= ' z ') return CH-' a ' + 26; if (ch >= ' 0 ' && ch <= ' 9') return CH-' 0 ' + 52; if (ch = = ' + ') return 62; else return 63;} void change (unsigned char str[], int len) {int t = 0; for (int i = 0; i < len; i+=4) {buf[t++] = ((str[i]<<2) | (str[i+1]>>4)); if (I+2 < len) buf[t++] = ((str[i+1]<<4) | (str[i+2]>>2)); if (I+3 < len) buf[t++] = ((str[i+2]<<6) | (Str[i+3])); } tot = t;} Trie Ac;int Main () {#ifdef sxk freopen ("In.txt", "R", stdin); #endif//sxk int n, m; while (scanf ("%d", &n) = = 1) {ac.init (); for (int i = 0; i < n; i++) {scanf ("%s", str); int len = strlen (str); while (str[len-1] = = ') len--; for (int j = 0; J < Len; j + +) S[j] = Get (Str[j]); Change (S, Len); Ac.insert (buf, tot, i); } ac.build (); scanf ("%d", &m); while (M-) {scanf ("%s", str); int len = strlen (str); while (StR[len-1] = = ' = ') len--; for (int j = 0; J < Len; j + +) S[j] = Get (Str[j]); Change (S, Len); printf ("%d\n", Ac.query (buf, tot, n)); } puts (""); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
ZOJ 3430 Detect the Virus (AC automaton)