Description
全国英语四级考试就这样如期到来了,可是小Y依然没有做好充分准备。为了能大学毕业,可怜的小Y准备作弊。
小Y费尽心机,在考试的时候夹带了一本字典进考场。现在的问题是:考试的时候可能有很多单词要查,小Y能不能来得及呢?
Input
第一行一个整数N,表示字典中一共有多少个单词。
接下来每两行表示一个单词,其中:第一行是一个长度≤100的字符串,表示这个单词,全部是小写字母,单词不会重复;第二行是一个整数,表示这个单词在字典中的页码。
接下来一行是一个整数M,表示要查的单词数。
接下来M行,每行一个字符串,表示要查的单词,保证在字典中存在。
N≤10000,M≤10000
Output
M行,每行一个整数,表示第i个单词在字典中的页码。
Sample Input
2
scan
10
word
15
2
scan
word
Sample Output
10
15
sol:
1.建Trie树,将读入的单词建立字典树,在单词结束位置记录下该单词的页码。
2.查找单词,从根结点开始,如果待查找单词的某个字符没找到,直接返回0,如果查找完毕,返回页码。
注意结点的存储,对于每个结点,既要存储结点的编号,又要存储相应的字符,定义二维数组来存储。第一维是结点的个数,第二维存储相应字符。所以第二维开26个字符空间大小。
代码如下:
1 #include<cstring> 2 #include<iostream> 3 using namespace std; 4 const int maxn=1e6+10; 5 int a[maxn][26],tot,End[maxn]; 6 void ins(char *str,int f) 7 { 8 int n=strlen(str),p=0;//从根结点出发,p为结点编号 9 for(int i=0;i<n;i++) 10 { 11 int l=str[i]-'a';//将字符转成对应的数值,a——0,b——1 12 if(!a[p][l])a[p][l]=++tot; 13 //编号为p的结点的l字符在树中没有,则新增一个结点 14 p=a[p][l]; 15 } 16 End[p]=f;//在单词结尾处记下该单词的页码 17 } 18 int find(char *str) 19 { 20 int n=strlen(str),p=0; 21 for(int i=0;i<n;i++) 22 { 23 int l=str[i]-'a'; 24 p=a[p][l]; 25 if(!p)return 0;//待查找单词的某个字符未找到,返回0 26 } 27 return End[p];//找到,返回页码 28 } 29 char str[110]; 30 int main() 31 { 32 int n,m; 33 scanf("%d",&n); 34 tot=0; 35 //tot代表一共有多少个点,默认根结点为0 36 for(int i=1;i<=n;i++) 37 { 38 int f; 39 scanf("%s%d",str,&f); 40 ins(str,f); 41 } 42 scanf("%d",&m); 43 for(int i=1;i<=m;i++) 44 { 45 scanf("%s",str); 46 printf("%d ",find(str)); 47 } 48 return 0; 49 }