COGS 293.[NOI2000] 单词查找树

                  ★   输入文件:trie.in   输出文件:trie.out   简单对比
                      时间限制:1 s   内存限制:128 MB

在进行文法分析的时候,通常需要检测一个单词是否在我们的单词列表里。为了提高查找和定位的速度,通常都要画出与单词列表所对应的单词查找树,其特点如下:

  • 根节点不包含字母,除根节点外每一个节点都仅包含一个大写英文字母;
  • 从根节点到某一节点,路径上经过的字母依次连起来所构成的字母序列,称为该节点对应的单词。单词列表中的每个词,都是该单词查找树某个节点所对应的单词;
  • 在满足上述条件下,该单词查找树的节点数最少。

单词列表对应的单词查找树

A
AN
ASP
AS
ASC
ASCII
BAS
BASIC Image:Trie.gif 

对一个确定的单词列表,请统计对应的单词查找树的节点数(包括根节点)

[输入文件]

该文件为一个单词列表,每一行仅包含一个单词和一个换行/回车符。每个单词仅由大写的英文字符组成,长度不超过63个字符。文件总长度不超过32K,至少有一行数据。

[输出文件]

该文件中仅包含一个整数和一个换行/回车符。该整数为单词列表对应的单词查找树的节点数。

[输入输出文件样例]

Input

A
AN
ASP
AS
ASC
ASCII
BAS
BASIC

Output

13
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<queue>
 8 #include<cstring>
 9 #include<set>
10 #include<map>
11 using namespace std;
12 char line[100];
13 struct letter{
14     char d;
15     int son,bro;
16 }tr[320000];
17 int tot;
18 void insert(char s[]){
19     int len=strlen(line);
20     int now=0;
21     for(int i=0;i<len;i++){
22         if(tr[now].son==0){
23             tr[++tot].d=s[i];
24             tr[now].son=tot;
25             now=tot;
26         }
27         else{
28             now=tr[now].son;
29             while(tr[now].d!=s[i]&&tr[now].bro>0){
30                 now=tr[now].bro;
31             }
32             if(tr[now].d!=s[i]){
33                 tr[++tot].d=s[i];
34                 tr[now].bro=tot;
35                 now=tot;
36             }
37         }
38     }
39 }
40 int main(){
41     freopen("trie.in","r",stdin);
42     freopen("trie.out","w",stdout);
43     while(scanf("%s",line)!=EOF){
44         insert(line);
45     }
46     printf("%d",tot+1);
47     return 0;
48 }
posted @ 2016-01-28 09:15  CXCXCXC  阅读(417)  评论(0编辑  收藏  举报