分析:依然是一个模板题,不过在写建立失败指针的地方竟然写错了三次....看来现在状态不太好。
代码如下:
=========================================================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std; const int MAXN = 2e6+7; const int MAXM = 26; const int oo = 1e9+37; char virus[1007][107], MumStr[MAXN]; int times[1007]; struct node { node *Fail, *next[MAXM]; int leaf; }; void Insert(node *root, char s[], int num) { node *p = root; for(int i=0; s[i]; i++) { int k = s[i] - 'A'; if(p->next[k] == NULL) p->next[k] = new node(); p = p->next[k]; } p->leaf = num; } void GetFail(node *root) { node *p = root, *temp; queue<node *> Q; for(int i=0; i<MAXM; i++)if(p->next[i]) {///竟然头晕的把这个地方写错了三次.... p->next[i]->Fail = root; Q.push(p->next[i]); } while(Q.size()) { p = Q.front(); Q.pop(); for(int i=0; i<MAXM; i++)if(p->next[i]) { temp = p->Fail; while(temp != NULL) { if(temp->next[i] != NULL) { p->next[i]->Fail = temp->next[i]; break; } temp = temp->Fail; } if(temp == NULL) p->next[i]->Fail = root; Q.push(p->next[i]); } } } void FreeTrie(node *root) { for(int i=0; i<MAXM; i++) { if(root->next[i]) FreeTrie(root->next[i]); } free(root); } void Query(node *root) { node *p = root, *temp; for(int i=0; MumStr[i]; i++) { if(MumStr[i] < 'A' || MumStr[i] > 'Z') {///排除不为大写英文的字符 p = root; continue; } int k = MumStr[i] - 'A'; while(!p->next[k] && p != root) p = p->Fail; if(!p->next[k])continue; temp = p = p->next[k]; while(temp != root) { if(temp->leaf) times[temp->leaf] += 1; temp = temp->Fail; } } } int main() { int N; while(scanf("%d", &N) != EOF) { node *root = new node(); memset(times, 0, sizeof(times)); for(int i=1; i<=N; i++) { scanf("%s", virus[i]); Insert(root, virus[i], i); } GetFail(root); scanf("%s", MumStr); Query(root); for(int i=1; i<=N; i++) { if(times[i]) printf("%s: %d ", virus[i], times[i]); } FreeTrie(root); } return 0; }