标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846
题目:输入个n个词典串,然后输入q个串,对这q个串分别输出每个串都是几个词典串的子串。
思路:因为要包含子串,比如abd,将串abd,bd,d都插入字典树,然后每个节点下统计子树个数,直接查找前缀就可以了。但需要注意dcda这种的,需要插入dcda,cda,da,a,这个时候d下面的子树应该是一个而不是2个,因为dcda和da属于同一个词典串。所以在插入的时候进行处理即可。
代码
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define ceil(x, y) (((x) + (y) - 1) / (y))
const int SIZE = 30;
const int N = 1e6 + 10;
const int INF = 0x7f7f7f7f;
struct Trie {
int val[SIZE];
int t;
int count;
};
int sz;
Trie pn[N];
int newnode() {
memset(pn[sz].val, 0, sizeof(pn[sz].val));
pn[sz].count = pn[sz].t = 0;
return sz++;
}
void init() {
sz = 0;
newnode();
}
void insert(char *s, int t, int c) {
int u = 0;
for (int i = t; s[i]; i++) {
int idx = s[i] - 'a';
if (!pn[u].val[idx]) {
pn[u].val[idx] = newnode();
}
u = pn[u].val[idx];
if (pn[u].t != c) {
pn[u].count++;
pn[u].t = c;
}
}
}
int findpre(char *s) {
int u = 0;
for (int i = 0; s[i]; i++) {
int idx = s[i] - 'a';
if (!pn[u].val[idx])
return 0;
u = pn[u].val[idx];
}
return pn[u].count;
}
int main() {
int n, q;
char str[SIZE];
while (scanf("%d", &n) != EOF) {
init();
for (int i = 1; i <= n; i++) {
scanf("%s", str);
for (int j = 0; str[j]; j++)
insert(str, j, i);
}
scanf("%d", &q);
for (int i_q = 1; i_q <= q; i_q++) {
scanf("%s", str);
printf("%d\n", findpre(str));
}
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u014357885/article/details/47701655