统计难题
【题目描述】
Ignatius最近遇到一个难题,老师交给他很多单词(只有小写字母组成,不会有重复的单词出现),现在老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀)。
【输入描述】
输入数据的第一行是下面单词表的单词数;
第二部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个数字代表单词表的结束以及提问数;
第三部分是一连串的提问,每行一个提问,每个提问都是一个字符串。
【输出描述】
对于每个提问,给出以该字符串为前缀的单词的数量。
【输入样例】
banana
band
bee
absolute
acm
ba
b
band
abc
【输出样例】
2
3
1
0
草泥马的Map解法:
源代码: #include<cstdio> #include<cstring> #include<string> #include<map> using namespace std; map <string,int> Num; char S[15]; int main() { char S[15]; while (gets(S)) { int Length=strlen(S); if (!Length) break; for (int a=Length;a>0;a--) { S[a]='\0'; //注意空白符。 Num[S]++; } } while (gets(S)) printf("%d\n",Num[S]); return 0; } /* 解题思路: 利用丧心病狂的STL中的map来联系所可能出现的字符串及其个数。 */
Trie解法:
源代码: #include<iostream> using namespace std; string n; int s,num(0); struct treetype { char t; int next,deep,same,son; }tree[1000001]; void x1(string s) { int m=s.size()-1,k(0); while (1) { if (tree[k].deep==m) break; //增点完毕。 if (tree[k].next==-1) //没有兄弟,直接增加儿子。 { num++; tree[num].deep=tree[k].deep+1; tree[num].t=s[tree[num].deep]; tree[num].same=-1; tree[num].next=-1; tree[num].son=1; tree[k].next=num; //终于有儿子了。 k=num; } else //有兄弟,遍历兄弟。 { k=tree[k].next; while (tree[k].t!=s[tree[k].deep]&&tree[k].same!=-1) //找与自己相同的兄弟。 k=tree[k].same; if (tree[k].t==s[tree[k].deep]) //找到了,当兄弟的儿子。 tree[k].son++; if (tree[k].t!=s[tree[k].deep]) //没找到,还当那个谁的儿子。 { num++; tree[num].deep=tree[k].deep; tree[num].t=s[tree[num].deep]; tree[num].same=-1; tree[num].next=-1; tree[num].son=1; tree[k].same=num; //又来了个兄弟。 k=num; } } } } int x2(string s) { int m=s.size()-1,k(0); while (1) { if (tree[k].deep==m) //前缀存在,返回儿子们的数量值。 return tree[k].son; if (tree[k].next==-1) //没前缀,自然为0。 return 0; k=tree[k].next; while (tree[k].t!=s[tree[k].deep]&&tree[k].same!=-1) //找与自己相同的兄弟。 k=tree[k].same; if (tree[k].t!=s[tree[k].deep]) //没找到与自己相同的兄弟,自然也为0。 return 0; } } int main() //字典树。 { tree[0].deep=0; tree[0].next=-1; tree[0].same=-1; tree[0].son=1; //已增加的点必定是它自己的儿子。 cin>>s; for (int a=1;a<=s;a++) { cin>>n; n=" "+n; //使字符串首位为1。 x1(n); } cin>>s; for (int a=1;a<=s;a++) { cin>>n; n=" "+n; printf("%d\n",x2(n)); } return 0; }