BY 九野
做了一道題,用我的那種寫法華麗麗的逾時了,,無奈學一學數組實現的
#include<stdio.h>#include<string.h>#include<queue>#include<iostream>using namespace std;const int maxnode=250*1000+10000;//maxnode=單詞數*單詞長度+常數const int sg_size=26;struct Trie{int ch[maxnode][sg_size];int val[maxnode];//該單詞在模式串出現的次數int last[maxnode];int f[maxnode];//失配函數int num[maxnode];//該單詞在文本串中出現的次數int pre[maxnode];//該單詞的前驅int len[maxnode];//以該單詞結尾的單詞長度int Char[maxnode];//該單詞對應的字母int road[maxnode];//路徑壓縮最佳化,針對模式串出現的種類int sz;int newnode(){val[sz]=f[sz]=last[sz]=len[sz]=num[sz]=0;memset(ch[sz],0,sizeof(ch[sz]));return sz++;}void init(){sz=0;newnode();}int idx(char c){return c-'A';}int insert(char *s){int u=0,i;for(i=0;s[i];i++){int c=idx(s[i]);if(!ch[u][c])ch[u][c]=newnode();pre[ch[u][c]]=u;Char[ch[u][c]]=s[i];len[ch[u][c]]=len[u]+1;road[ch[u][c]]=1;u=ch[u][c];}val[u]=1;num[u]=0;return u;}void getfail(){queue<int>q;int i;for(i=0;i<sg_size;i++){if(ch[0][i])q.push(ch[0][i]);}int r,c,u,v;while(!q.empty()){r=q.front();q.pop();for(c=0;c<sg_size;c++){u=ch[r][c];if(u)continue;q.push(u);v=f[r];while(v&&ch[v][c]==0)v=f[v];//沿失配邊走上去 如果失配後有節點 且 其子節點c存在則結束迴圈 f[u]=ch[v][c];}}}void find(char *s){ //計算模式串出現的個數:(每種多次出現算多次) int j=0;for(int i=0;s[i];i++){int c=idx(s[i]);while(j&&ch[j][c]==0)j=f[j];j=ch[j][c];int temp=j;while(temp){num[temp]++;temp=f[temp];}}}void find_kind(char *s,int &ans){//計算種數, 重複出現的不再計算(若多個詢問則要在此處加for(i=0->sz)lu[i]=1; int j=0,i,c,temp;for(i=0;s[i];i++){c=idx(s[i]);while(j&&ch[j][c]==0)j=f[j];j=ch[j][c];temp=j;while(temp&&road[temp]){if(val[temp]){++ans;val[temp]=0;}road[temp]=0;temp=f[temp];}}}}ac;int main(){}