COGS 293.[NOI2000] 单词查找树
★ 输入文件:trie.in
输出文件:trie.out
简单对比
时间限制:1 s 内存限制:128 MB
在进行文法分析的时候,通常需要检测一个单词是否在我们的单词列表里。为了提高查找和定位的速度,通常都要画出与单词列表所对应的单词查找树,其特点如下:
- 根节点不包含字母,除根节点外每一个节点都仅包含一个大写英文字母;
- 从根节点到某一节点,路径上经过的字母依次连起来所构成的字母序列,称为该节点对应的单词。单词列表中的每个词,都是该单词查找树某个节点所对应的单词;
- 在满足上述条件下,该单词查找树的节点数最少。
单词列表对应的单词查找树
A
AN
ASP
AS
ASC
ASCII
BAS
BASIC
对一个确定的单词列表,请统计对应的单词查找树的节点数(包括根节点)
[输入文件]
该文件为一个单词列表,每一行仅包含一个单词和一个换行/回车符。每个单词仅由大写的英文字符组成,长度不超过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 }