利用Trie图模板解决多模匹配问题(HDU3695)

    今天刚刚把Trie图的模板弄到了,并且解决一个简单的多模匹配的问题HDU2222,想到上次做福州赛区的那道题,今天就套模板做了一下,很快乐地就AC了! 呵呵……其实也没那么顺利!

     第一次提交超空间了!主要是我傻呼呼的把子串反过来插入Trie图中,后来看书上,原来是把母串反转,然后再查一次就OK了!

      第二次提交果断WA了,后来打印解压的结果才发现,自己忘记了把解压缩的母串末尾加上结束符 s[end]='\0';

      第三次提交果断AC了!不管怎么样,感觉挺爽的 呵呵!

把代码贴上来吧!

  
  
  
  
  1. /* 
  2.  * Trie图:解决多串匹配问题 
  3.  * hdu2222 
  4.  * */ 
  5. #include<stdio.h> 
  6. #include<string.h> 
  7. #include<queue> 
  8. using namespace std; 
  9. #define M   6000000 
  10. char word[1105]; 
  11. char ds[M]; 
  12. char s[M]; 
  13. char rs[M]; 
  14. struct Node{ 
  15.     int tail; 
  16.     Node *prefix; 
  17.     Node *next[26]; 
  18.     Node(){ 
  19.         memset(next,0,sizeof(next)); 
  20.         tail=0; 
  21.     } 
  22. }*root; 
  23. void init(){ 
  24.     root=new Node(); 
  25. void insert(char *word){ 
  26.     Node *p=root; 
  27.     int idx; 
  28.     while(*word){ 
  29.         idx=*word-'A'
  30.         if(p->next[idx]==0){ 
  31.             p->next[idx]=new Node(); 
  32.         } 
  33.         p=p->next[idx]; 
  34.         word++; 
  35.     } 
  36.     p->tail++; 
  37. void add_prefix(){ 
  38.      root->prefix = NULL; 
  39.     deque<Node* > q; 
  40.     q.push_back(root); 
  41.  
  42.     while(!q.empty()) { 
  43.         Node* tmp = q.front(); 
  44.         Node* p = NULL; 
  45.         q.pop_front(); 
  46.         for(int i = 0; i < 26; ++i) { 
  47.             if(tmp->next[i] != NULL) { 
  48.                 if(tmp == root) tmp->next[i]->prefix = root; 
  49.                 else { 
  50.                     p = tmp->prefix; 
  51.                     while(p != NULL) { 
  52.                         if(p->next[i] != NULL) { 
  53.                             tmp->next[i]->prefix = p->next[i]; 
  54.                             break
  55.                         } 
  56.                         p = p->prefix; 
  57.                     } 
  58.                     if(p == NULL)   tmp->next[i]->prefix = root; 
  59.                 } 
  60.                 q.push_back(tmp->next[i]); 
  61.             } 
  62.         } 
  63.     } 
  64. void reverse(char *s){ 
  65.     int len=strlen(s); 
  66.     int i,j; 
  67.     for(i=len-1,j=0;i>=0;i--){ 
  68.         rs[j++]=s[i]; 
  69.     } 
  70.     rs[j]=0; 
  71.     //printf("rs=%s\n",rs); 
  72. int search(char *st){ 
  73.     int cnt = 0, t; 
  74.             Node* p = root; 
  75.             while(*st) { 
  76.                 t = *st - 'A'
  77.                 while(p->next[t] == NULL && p != root) { 
  78.                     p = p->prefix; 
  79.                 } 
  80.                 p = p->next[t]; 
  81.                 if(p == NULL)   p = root; 
  82.  
  83.                 Node* tmp = p; 
  84.                 while(tmp != root && tmp->tail != -1) { 
  85.                     cnt += tmp->tail; 
  86.                     tmp->tail = -1; 
  87.                     tmp = tmp->prefix; 
  88.                 } 
  89.                 st++; 
  90.             } 
  91.      return cnt; 
  92. //把字符串解压缩出来 
  93. void decode(){ 
  94.     int len_ds=strlen(ds); 
  95.     int i,j,k,len; 
  96.     i=j=0; 
  97.     while(i<len_ds){ 
  98.         if(ds[i]>='A'&&ds[i]<='Z'){ 
  99.             s[j++]=ds[i]; 
  100.         }else if(ds[i]=='['){ 
  101.             i++;//把']'跳过 
  102.             len=0; 
  103.             while(ds[i]>='0'&&ds[i]<='9'){ 
  104.                 len=len*10+(ds[i]-'0'); 
  105.                 i++; 
  106.             }//已经跳到了字母 
  107.             for(k=0;k<len;k++){ 
  108.                 s[j++]=ds[i]; 
  109.             } 
  110.             i++;//跳到']'的位置 
  111.         } 
  112.         i++; 
  113.     } 
  114.     s[j]=0;//这句一定不能少了!我的一次WA就贡献在这里了 
  115. //  printf("decode:%s\n",s); 
  116. int main(){ 
  117.     int t,n,i; 
  118.     scanf("%d",&t); 
  119.     while(t--){ 
  120.         init(); 
  121.         scanf("%d",&n); 
  122.         for(i=0;i<n;i++){ 
  123.             scanf("%s",word); 
  124.             insert(word); 
  125.         } 
  126.         add_prefix(); 
  127.         scanf("%s",ds); 
  128.         decode();reverse(s); 
  129.         printf("%d\n",search(s)+search(rs)); 
  130.     } 

 

你可能感兴趣的:(多模匹配,Trie图,HDU3695,多串匹配)