//思路:使用字典树算法
//首先把每个单词按照其后缀子串放入到字典树,比如:abcd,我们应该吧abcd, bcd, cd, d都放入字典树中
//这里有个问题:同样一个字符串例如:abab,当查找ab时,就会重复计数,所以我们在建树的过程要多加一个标识符
//这个标识符表示该子串是不是重复出现在某一个字符串中,并且该字符串总是表示建树过程中最后一个字符串的编号
//如果插入的子串编号同当前的字符串编号不同,则计数+1,并且将当前节点的标识符设为要插入子串的编号
//否则不处理该子串
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define N 26
typedef struct Node_
{
Node_()
{
id = 0;
wordnum = 1;
for (int i = 0;i < N;i++)
{
next[i] = 0;
}
}
int id;
int wordnum;
struct Node_ * next[N];
}Node;
Node * root = 0;
int tree_insert(char * word, int id)
{
if (root == 0)
{
root = new Node();
}
int len = strlen(word);
Node * tmpNode = root;
int site = 0;
for (int i = 0;i < len;i++)
{
site = word[i] - 'a';
if (tmpNode->next[site] == 0)
{
tmpNode->next[site] = new Node();
tmpNode->next[site]->id = id;
}
else
{
if (tmpNode->next[site]->id != id)
{
tmpNode->next[site]->id = id;
tmpNode->next[site]->wordnum++;
}
}
tmpNode = tmpNode->next[site];
}
return 1;
}
int tree_search(char * index)
{
Node * tmpNode = root;
int len = strlen(index);
int site = 0;
for (int i = 0; i< len; i++)
{
site = index[i] - 'a';
if (tmpNode->next[site] == 0)
{
printf("0\n");
return 0;
}
tmpNode = tmpNode->next[site];
}
printf("%d\n", tmpNode->wordnum);
return 0;
}
int main()
{
int t, n, q, i, j, len;
char tmpStr[N];
scanf("%d", &n);
for (i = 0;i < n;i++)
{
scanf("%s", tmpStr);
len = strlen(tmpStr);
for (j = 0;j < len;++j)
{
tree_insert(tmpStr + j, i);
}
}
scanf("%d", &q);
for(i = 0;i < q; i++)
{
scanf("%s", tmpStr);
tree_search(tmpStr);
}
return 0;
}