题目:
20 ad ae af ag ah ai aj ak al ads add ade adf adg adh adi adj adk adl aes 5 b a d ad s
0 20 11 11 2
//该题是字典树的变形题目,一般字典树能查找某字符串 //出现的次数或者以某些字符串为前缀的字符串出现的次 //数,不能查找该题所描述的情况。故插入字符串时,假 //设字符串为x1x2x3....xn,则插入时以x1为开头插入,以 //x2为开头插入,一直到以xn为开头插入,为避免如abab //的字符串重复计数,故插入时增加一个标记变量id,若为 //同一个id,则count值不增加,否则增加 #include <iostream> #include <cstdio> using namespace std; struct Tire{//定义字典树 int count; int id;//标记是不是同一个字符串 struct Tire *tire[26]; }*a;//tire void init(){//初始化字典树的函数 a=(Tire*)malloc(sizeof(Tire));//动态分配内存 a->id=-1; for(int i=0;i<26;++i) a->tire[i]=NULL; }//init void insert(char ss[],int newid){//字典树的插入函数 int len=strlen(ss); Tire *head=a; for(int i=0;i<len;++i){ int k=ss[i]-'a'; if(head->tire[k]==NULL){//无该结点 Tire *newhead=new Tire;//分配新的字典树 for(int j=0;j<26;++j) newhead->tire[j]=NULL;//初始化新分配的结点 newhead->count=0; newhead->id=-1; head->tire[k]=newhead;//结点之间赋值 }//if head=head->tire[k]; if(head->id!=newid){//如果不是同一个串的话,则count值加1,否则不加,避免重复 head->id=newid; head->count++; } }//for }//insert int search(char ch[]){//字典树的查找函数 int len=strlen(ch); Tire *head=a; for(int i=0;i<len;++i){ int k=ch[i]-'a'; if(head->tire[k]==NULL)//不存在这样的串,故返回0 return 0; else{ head=head->tire[k];//继续往下找 } }//for return head->count; }//search void del(Tire *root){//释放内存的函数 for(int i=0;i<26;++i){ if(root->tire[i]!=NULL) del(root->tire[i]);//递归寻找叶子结点 delete(root->tire[i]);//删除函数 }//for }//del int main(){ //freopen("1.txt","r",stdin); int num; char ss[22]; init(); scanf("%d",&num); for(int i=1;i<=num;++i){ scanf("%s",ss); for(int j=0;j<strlen(ss);++j) insert(ss+j,i);//插入字符串和字符串的序号,作为标记变量 }//while int sum; char newss[22]; scanf("%d",&sum); while(sum--){ scanf("%s",newss); int x=search(newss); printf("%d\n",x); }//while del(a); return 0; }//main