HDU 1251 统计难题 字符匹配

题目描述:先说明此题只有一个测试实例,然后输入一系列的单词,以一个回车为结束符,然后输入一个字符串,要你查找以这个字符串为前缀的单词的个数,处理到文件结束。

解题报告:一开始看到这题,竟然直接用暴力去解了,根本没有想到用字典树,因为字典树是很久以前学的了,刚学的时候一个题都没做,所以现在都忘了,还好这题一次就写出来了,还没有调试,用字典树,要注意的是,一般字典树是在每个点标记有没有以这个点没结束的单词,但是这里要将每个节点标记的成经过这个节点的次数,因为可能有多个单词的前缀相同,这样就会多次经过这个点,如果只标记是否走过的话,就没有办法统计次数了。代码附上:

 1 #include<cstdio>
 2 #include<cstring>
 3 
 4 typedef struct node {
 5     char c;
 6     int flag;
 7     node *next[26];
 8     node() {         //各种初始化
 9         flag = 0;
10         for(int i = 0;i<26;++i)
11         next[i] = NULL;
12     }
13 }Trie;
14 void push(Trie *head,char *s) {    //插入字符串
15     int len = strlen(s);
16     Trie *p = head;
17     for(int i = 0;i<len;++i) {
18         if(p->next[s[i]-'a'] == NULL) {
19             p->next[s[i]-'a'] = new Trie;
20             p->next[s[i]-'a']->c = s[i];
21             p->next[s[i]-'a']->flag++;   //这里要注意因为插入的字符串前缀相同的可能有多个,所以应该统计个数,而不是标记是否存在
22             p = p->next[s[i]-'a'];
23         }
24         else if(p->next[s[i]-'a'] != NULL) {
25             p->next[s[i]-'a']->flag++;
26             p = p->next[s[i] -'a'];
27         }
28     }
29 }
30 int serch(Trie *head,char *s) {
31      int len = strlen(s);
32      Trie *p = head;
33      for(int i = 0;i<len;++i) {
34          if(p->next[s[i]-'a'] == NULL)
35          return 0;    //不能走到末尾的字符,直接返回0;
36          else p = p->next[s[i]-'a'];
37          if(i == len-1)
38          return p->flag;
39      }
40 }
41 void Delete(Trie *head) {
42     Trie *p = head;
43     for(int i = 0;i<26;++i) {
44         if(p->next[i] != NULL)
45         p = p->next[i];
46         else {
47             delete p;
48             return ;
49         }
50     }
51 }
52 
53 
54 int main() {
55     Trie *head = new Trie;
56     char s[12];
57     while(gets(s))
58     if(s[0] != NULL)
59     push(head,s);
60     else break;
61     while(scanf("%s",s)!=EOF)
62     printf("%d\n",serch(head,s));
63     Delete(head);       //清理内存
64     return 0;
65 }
View Code

 

posted @ 2013-07-31 10:41  xiaxiaosheng  阅读(256)  评论(0编辑  收藏  举报