POJ - 1816 Wild Words(字典树变题)

来源:互联网 发布:上瘾网络剧韩国 编辑:程序博客网 时间:2024/06/01 21:57
Wild Words
Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u

Submit Status

Description

A word is a string of lowercases. A word pattern is a string of lowercases, '?'s and '*'s. In a pattern, a '?' matches any single lowercase, and a '*' matches none or more lowercases. 

There are many word patterns and some words in your hand. For each word, your task is to tell which patterns match it. 

Input

The first line of input contains two integers N (0 < N <= 100000) and M (0 < M <=100), representing the number of word patterns and the number of words. Each of the following N lines contains a word pattern, assuming all the patterns are numbered from 0 to N-1. After those, each of the last M lines contains a word. 

You can assume that the length of patterns will not exceed 6, and the length of words will not exceed 20. 

Output

For each word, print a line contains the numbers of matched patterns by increasing order. Each number is followed by a single blank. If there is no pattern that can match the word, print "Not match".

Sample Input

5 4t*?h*s??e**s?*ethistheanis

Sample Output

0 1 3 0 2 4 Not match3

#include<cstdio>#include<algorithm>#include<cstring>#include<ctime>#define MAXN 100010using namespace std;int n, m;struct Trie{int i;Trie *a[28];Trie(){for (i = 0; i<28; i++)a[i] = NULL;        //插入字典树,并置结点后代为空i = -1;                 //模式串“不是”最后结点用-1标记}};Trie root;char p[7], s[22];int set[MAXN];bool mat[MAXN];void Insert(Trie *rt, int k, int j)        //字典树蛋疼的地方是不能重复存相同的模板串,用set[k],k表示模式串的原编号,set[k]存的数字是字典树中的编号{                                          //再插入和查找时都应该多加注意。int i, t;if (p[j] == '\0')                      //i字典树中各个模式串的编号,无重复。{if (rt->i>-1)set[k] = set[rt->i];            //set【k】是表中的编号,有重复。后面的模式串与前面的相同,则指向同一个i。elsert->i = k;                      //新串return;}if (p[j] == '*')t = 27;else if (p[j] == '?')t = 26;elset = p[j] - 'a';        //0到27分别为a到z和?、*if (!rt->a[t]){rt->a[t] = new Trie;}Insert(rt->a[t], k, j + 1);}void Query(Trie *rt, int j)              //dfs{if (rt->a[27] && rt->a[27]->i>-1)    //模式串最后为*,后面再无字符,匹配mat[rt->a[27]->i] = true;if (s[j] == '\0'){if (rt->i>-1)mat[rt->i] = true;return;}if (rt->a[s[j] - 'a'])Query(rt->a[s[j] - 'a'], j + 1);if (rt->a[26])Query(rt->a[26], j + 1);if (rt->a[27])for (int i = j; s[i] != '\0'; i++)   //*可以代替任意个字母Query(rt->a[27], i);}int main(){int i, j, k;scanf("%d%d", &n, &m);root.i = -1;for (i = 0; i<28; i++)root.a[i] = NULL;for (i = 0; i<n; i++){set[i] = i;scanf("%s", p);for (j = k = 0; p[j] != '\0'; j++)if (!(p[j] == '*'&&p[j + 1] == '*'))  //多个*的等价省略p[k++] = p[j];p[k] = '\0';Insert(&root, i, 0);}for (i = 0; i<m; i++){scanf("%s", s);memset(mat, false, sizeof(mat));      //mat[j]用来记录模式串set[j]与查找串是否匹配Query(&root, 0);for (j = k = 0; j<n; j++)if (mat[j] || mat[set[j]])mat[j] = true, k++;if (!k)puts("Not match");else{for (j = 0; j<n; j++)if (mat[j])printf("%d ", j);putchar('\n');}}return 0;}


0 0