这个题要查询是以某个串为前缀的串的个数
那么我们可以利用val数组,初始为0,然后每次插入一个字符串的时候就令该串的所有节点val值+1
最后要查询的串的最后一个字符所对应的编号的val值就是以查询串为前缀的串的个数
这里再说下字典树的ch[i][j]记录的是编号为i的节点的子节点j的编号
比如说ab这个串,当a编号是7时,ch[7][‘b’-‘a’]储存的就是b的编号
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
const int N=1000000+5;
int ch[N][30];
char s[12];
int val[N];
int sz,ans;
int idx(char c)
{
return c-'a';
}
void Inser(char *s)
{
int u=0,n=strlen(s);//每次从根节点开始
for(int i=0;i<n;i++)
{
int c=idx(s[i]);
if(!ch[u][c])//如果有新的节点
{
memset(ch[sz],0,sizeof(ch[sz]));
ch[u][c]=sz++;//新节点的编号
}
u=ch[u][c];//沿着当前串向下走
val[u]++;//用过一次就增加一次
}
}
int Find(char *s)//为了找到查询串的最后那个字符的编号
{
int u=0,n=strlen(s),c;
for(int i=0;i<n;i++)
{
c=idx(s[i]);
u=ch[u][c];
if(!u) return 0;//这个地方要注意判断是否有这个前缀
}
return val[u];
}
void ini()
{
sz=1;
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
}
int main()
{
ini();
while(gets(s) && s[0]>='a' && s[0]<='z') Inser(s);
while(gets(s))
{
ans=0;
printf("%d\n",Find(s));
}
return 0;
}