hdu Repositoryti

算法:字典树

题意:给你一些字符串,然后会有一些询问,输出询问在给定的字符串中出现了多少次(字串也是);

例如 add,子串有:a ,d,d,ad ,dd,add;你会发现子串d出现了两次,那么怎么办呢;这就需要

一个标记符号,如果存在有相同的子串就不做处理;

Problem Description
When you go shopping, you can search in repository for avalible merchandises by the computers and internet. First you give the search system a name about something, then the system responds with the results. Now you are given a lot merchandise names in repository and some queries, and required to simulate the process.


Input
There is only one case. First there is an integer P (1<=P<=10000)representing the number of the merchanidse names in the repository. The next P lines each contain a string (it's length isn't beyond 20,and all the letters are lowercase).Then there is an integer Q(1<=Q<=100000) representing the number of the queries. The next Q lines each contains a string(the same limitation as foregoing descriptions) as the searching condition.


Output
For each query, you just output the number of the merchandises, whose names contain the search string as their substrings.


Sample Input
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


Sample Output
0
20
11
11
2
代码:

#include <iostream>
#include <cstring>
#include <iomanip>
#include <string>
#include <algorithm>
#include <stdio.h>
#include <cmath>
#define Max 27
using namespace std;
struct dot 
{
	dot *next[Max];
	int flag;
	int v;
	int num;//用来标记当前是第几个字符串 
};
dot *newnode()
{
	dot *temp=new dot;
	temp->flag=0;
	temp->v=0;
	for(int i=0;i<Max;i++)
	    temp->next[i]=0;
	return temp;
}
void tree(char *st,int &k,dot *root,int n)
{
	dot *p=root;
	int id=0;
	for(int i=k;i<strlen(st);i++)
	{
		id=st[i]-'a';
		if(p->next[id]==0)
		   p->next[id]=newnode();	
		p=p->next[id];
        if(p->num!=n)//用来判断是否是同一个字符串; 
		   {p->v++;
		    p->num=n;
		   }
	}
	p->flag=1;
} 
int find(char *st,dot *root)
{
	dot *p=root;
	int id=0;
	for(int i=0;i<strlen(st);i++)
	{
		id=st[i]-'a';
		if(p->next[id]==0)
		    return 0;
		p=p->next[id];
	}
	return p->v;
}
int main()
{
	int n,m,i,j,k;
	char st[21];
	dot *root=new dot;
	root=newnode();
	cin>>n;
	while(n--)
	{
		cin>>st;
		for(k=0;k<strlen(st);k++)
		   tree(st,k,root,n+1);
	}
	cin>>m;
	while(m--)
	{
		cin>>st;
		cout<<find(st,root)<<endl;
	}
	return 0;
}


posted @ 2015-12-04 11:17  (慎独)  阅读(155)  评论(0编辑  收藏  举报