您的位置:首页 > 其它

hdu2846(动态字典树||静态字典树 模板)Repository

2017-07-18 16:51 197 查看


Repository

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 5464    Accepted Submission(s): 1832


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<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int mn=500010;
int tot,n;
int str[mn][26];
int vis[mn];//标志该条路径的字符
int num[mn];//记录到达该结点的个数
void creat(char* s,int k)
{
int len=strlen(s),p=0;
for(int i=0;i<len;++i)
{
int id=s[i]-'a';
if(!str[p][id]) str[p][id]=tot++;
p=str[p][id];
if(vis[p]!=k)
{
num[p]++;
vis[p]=k;
}
}
}
int find(char* s)
{
int p=0,len=strlen(s);
for(int i=0;i<len;++i)
{
int id=s[i]-'a';
if(!str[p][id]) return 0;
p=str[p][id];
}
return num[p];
}
int main()
{
char s[21],st[21];
int l=sizeof(char);
while(~scanf("%d",&n))
{
memset(str,0,sizeof(str));
memset(num,0,sizeof(num));
tot=1;
while(n--)
{
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;++i)
{
//memcpy(st,s+i,(len-i+1)*l);
memcpy(st,s+i,len-i+1);
creat(st,n+1);
}
}
scanf("%d",&n);
while(n--)
{
scanf("%s",s);
printf("%d\n",find(s));
}
}
return 0;
}

//动态字典树
//字符串的复制要注意多复制一位
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
struct Tire{
int num,vis;
Tire *next[26];
Tire()
{
num=0,vis=0;
//用malloc构建一个结点,这个num的初始化居然会出错
for(int i=0;i<26;++i)
next[i]=NULL;
}
};
Tire *root=new Tire;
void creat(char* s,int k)
{
int len=strlen(s);
Tire *p=root;
for(int i=0;i<len;++i)
{
int id=s[i]-'a';
if(p->next[id]==NULL)
p->next[id]=new Tire;
p=p->next[id];
if(p->vis!=k)
{
p->num++;//两个运算符同一优先级,从左到右
p->vis=k;
}
}
}
int find(char* s)
{
int len=strlen(s);
Tire *p=root;
for(int i=0;i<len;++i)
{
int id=s[i]-'a';
if(p->next[id]==NULL) return 0;
p=p->next[id];
}
return p->num;
}
void Delete(Tire* p)
{
//释放字典树的空间
for(int i=0;i<26;i++)
if(p->next[i]) Delete(p->next[i]);
delete(p);
}
int main()
{
char s[21],st[21];
int l=sizeof(char),n;
while(~scanf("%d",&n))
{
root=new Tire;
while(n--)
{
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;++i)
{
//memcpy(st,s+i,(len-i+1)*l);
memcpy(st,s+i,len-i+1);
creat(st,n+1);
}
}
scanf("%d",&n);
while(n--)
{
scanf("%s",s);
printf("%d\n",find(s));
}
Delete(root);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: