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

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 4
t*
?h*s
??e*
*s
?*e
this
the
an
is

Sample Output

0 1 3 
0 2 4 
Not match
3

#include
#include
#include
#include
#define MAXN 100010
using 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。
		else
			rt->i = k;                      //新串
		return;
	}
	if (p[j] == '*')
		t = 27;
	else if (p[j] == '?')
		t = 26;
	else
		t = 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


你可能感兴趣的:(字符串,数据结构)