HDU_2222 大部分是别人的,有的地方稍有改动,代码有不完善的地方!

大部分是别人的,有的地方稍有改动
[cpp]
  view plain copy
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<cstring>  
  4. #include<string>  
  5. using namespace std;  
  6. #define N 500010  
  7. char str[1000010], keyword[51];  
  8. int head, tail;  
  9.   
  10. struct node  
  11. {  
  12.     node *fail;  
  13.     node *next[26];  
  14.     int count;  
  15.     node() //初始化,(类似于构造函数)
  16.     {  
  17.         fail = NULL;  
  18.         count = 0;  
  19.         for(int i = 0; i < 26; ++i)  
  20.             next[i] = NULL;  
  21.     }  
  22. }*q[N];  
  23. node *root;  
  24. void trie(char *keyword) //建立Trie,每次只能建立一个keyword。  
  25. {  
  26.     int temp, length;  
  27.     node *p = root;  
  28.     length = strlen(keyword);  
  29.     for(int i = 0; i < length; ++i)  
  30.     {  
  31.         temp = keyword[i] - 'a';  
  32.         if(p->next[temp] == NULL)  
  33.             p->next[temp] = new node();  
  34.         p = p->next[temp];  
  35.     }  
  36.     p->count++;  
  37. }   
  38. void build_ac() //初始化fail指针,BFS  
  39. {  
  40.     q[tail++] = root;  
  41.     while(head != tail)  
  42.     {  
  43.         node *p = q[head++]; //弹出队头  
  44.         node *temp = NULL;  
  45.         for(int i = 0; i < 26; ++i)  
  46.         {  
  47.             if(p->next[i] != NULL)  
  48.             {  
  49.                 if(p == root) //第一个元素fail必指向根  
  50.                     p->next[i]->fail = root;  
  51.                 else  
  52.                 {  
  53.                     temp = p->fail; //失败指针  
  54.                     while(temp != NULL) //2种情况结束:匹配为空or找到匹配  
  55.                     {  
  56.                         if(temp->next[i] != NULL) //找到匹配  
  57.                         {  
  58.                             p->next[i]->fail = temp->next[i];  
  59.                             break;  
  60.                         }  
  61.                         temp = temp->fail;  
  62.                     }  
  63.                     if(temp == NULL) //为空则从头匹配  
  64.                         p->next[i]->fail = root;  
  65.                 }  
  66.                 q[tail++] = p->next[i]; //入队  
  67.             }  
  68.         }  
  69.     }  
  70. }   
  71. int query() //扫描  
  72. {  
  73.     int index, length, result;  
  74.     node *p = root; //Tire入口  
  75.     result = 0;  
  76.     len = strlen(str);  
  77.     for(int i = 0; i < length; ++i)  
  78.     {  
  79.         index = str[i] - 'a';  
  80.         while(p->next[index] == NULL && p != root) //跳转失败指针  
  81.             p = p->fail;  
  82.         p = p->next[index];  
  83.         if(p == NULL)  
  84.             p = root;  
  85.         node *temp = p; //p不动,temp计算后缀串  
  86.         while(temp != root && temp->count != -1)  
  87.         {  
  88.             result += temp->count;  
  89.             temp->count = -1;  
  90.             temp = temp->fail;  
  91.         }  
  92.     }  
  93.     return result;  
  94. }    
  95. int main()  
  96. {  
  97.     int ncase, number;  
  98.     scanf("%d", &ncase);  
  99.     while(ncase--)  
  100.     {  
  101.         head= tail = 0;  
  102.         root = new node();  
  103.         scanf("%d", &number);  
  104.         getchar();  
  105.         for(int i = 0; i < number; ++i)  
  106.         {  
  107.             gets(keyword);  
  108.             trie(keyword);  
  109.         }  
  110.         build_ac();  
  111.         scanf("%s", str);  
  112.         printf("%d\n", query());  
  113.     }  
  114.     return 0;  
  115. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值