大致题意:给出一些单词,再给出一些字符串,问对每个提问给出以该字符串为子串的单词的数量
测试案例:
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
output:
0
20
11
11
2
解题思路:这题使用Trie树可以解,通过每个单词将其拆成他们从左到右的子串,如abc,拆成abc,bc,c进行插入用于处理子串问题,通过设置id值,防止如aa进行插入时将一个单词的a弄成2个的情况发生
代码(此题我g++显示超时,用c++过的):
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct Trie
{
int num,id;
Trie* next[26];
Trie()
{
id=-1;
num=0;
for (int i=0; i<26; i++)
{
next[i]=NULL;
}
}
};
Trie *tree=new Trie();
void Insert(char word[],int id)
{
Trie* p=tree;
int i;
for (i=0; word[i]; i++)
{
int t=word[i]-'a';
if (p->next[t]==NULL)
{
p->next[t]=new Trie();
}
p=p->next[t];
if (p->id!=id)
p->num++;
p->id=id;
}
}
int getnum(Trie *p,char word[])
{
for (int i=0; word[i]; i++)
{
int t=word[i]-'a';
if (p->next[t]!=NULL)
{
p=p->next[t];
}
else
return 0;
}
return p->num;
}
void freetree(Trie *p)
{
for (int i=0; i<26; i++)
{
if (p->next[i]!=NULL)
{
freetree(p->next[i]);
}
}
delete(p);
}
int main()
{
char s[21];
int n,m;
scanf("%d",&n);
for (int i=0;i<n;i++)
{
scanf("%s",&s);
for (int j=0;j<strlen(s);j++)
Insert(s+j,i);
}
scanf("%d",&m);
for (int i=0;i<m;i++)
{
scanf("%s",&s);
int ans=0;
ans=getnum(tree,s);
printf("%d\n",ans);
}
freetree(tree);
return 0;
}