题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1251
题面:
banana band bee absolute acm ba b band abc
2 3 1 0
题意:
额,中文大家都懂。
解题:
字典树裸题,val值统计经过该点的字母数量。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; struct Trie { //用来储存该节点的26个字母下标,ch的第一维要注意,要开大,不然会T int ch[1000010][26]; //val数组一般用来存储权值,视题目灵活运用,sz是当前节点数量 int val[1000010],sz; //初始化 void init() { sz=1; memset(ch[0],0,sizeof(ch[0])); } //插入一条单词 void insert(string s) { //u是节点编号,并不是层数 int u=0,len=s.length(); for(int i=0;i<len;i++) { //取下标 int c=(s[i]-'a'); //如果该节点不存在,创建该节点 if(!ch[u][c]) { //真的是相当的省 memset(ch[sz],0,sizeof(ch[sz])); //因为刚创建所以为1 val[sz]=1; //给该节点分配编号 ch[u][c]=sz++; //下移 u=ch[u][c]; } //已经存在了 else { //下移,并计数值加一 u=ch[u][c]; val[u]++; } } } //查询前缀 int query(string s) { int len=s.length(),u=0,c; //不断下移,直至移到给定的前缀的最后一个单词 bool sign=true; for(int i=0;i<len;i++) { c=s[i]-'a'; if(ch[u][c]) u=ch[u][c]; else { sign=false; break; } } if(sign) return val[u]; else return 0; } }; Trie T; int main() { string s; T.init(); while(getline(cin,s)) { if(s=="")break; T.insert(s); } while(getline(cin,s)) { cout<<T.query(s)<<endl; } return 0; }