POJ1816--Wild Words(Trie+搜索)

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
题意:给出m个字符串由小写字母和*?组成,给n个纯字母的单词,

?可以代表一个字母,*可以代表任意多个字母包括0个,对每个单词,从m个模板中找出所有可能的匹配

思路:算法不难想。将模式串构建trie。然后将单词一个个在trie上跑。此题模式串要判重。。。就是说有两个模式串都是abc。现在有个单词abc。那么两个都符合,都要输出。

#include 
#include 
#include 
#include 
using namespace std;
#define maxn 600800
bool vis[maxn];
vector  ans[maxn];
struct Trie
{
	int first[maxn],ch[maxn];
	int nxt[maxn],val[maxn];
	int cnt;
	void init()
	{
		val[0] = 0;
		first[0] = -1;
		cnt = 1;
	}
	void insert(char * s,int num)
	{
		int len = strlen(s);
		int u = 0;
		for(int i = 0;i < len;i++)
		{
			int id = s[i];
			int j;
			bool flag = false;
			for(j = first[u];j != -1;j = nxt[j])
			{
				if(ch[j] == id)
				{
					flag = true;
					break;
				}
			}
			if(!flag)
			{
				ch[cnt] = id;
				first[cnt] = -1;
				nxt[cnt] = first[u];
				val[cnt] = 0;
				first[u] = cnt++;
			}
			if(flag)	u = j;
			else u = cnt-1;
		}
		ans[u].push_back(num);
	}

	void find(int u,char * s)
	{
		int len = strlen(s);
		int id = s[0];
		if(len == 0)	
		{
			for(int i = 0;i < ans[u].size();i++)
				vis[ans[u][i]] = 1;
		}
		for(int i = first[u];i != -1;i = nxt[i])
		{
			if(ch[i] == '*')
			{
				for(int j = 0;j <= len;j++)
					find(i,&s[j]);
			}
			if(len == 0)	continue;
			if(ch[i] == id || ch[i] == '?')
			{
				find(i,&s[1]);
			}
		}
	}
}trie;

int main()
{
	//freopen("in.txt","r",stdin);
	int n,m;
	while(scanf("%d%d",&n,&m)==2)
	{
		trie.init();
		for(int i = 0;i < maxn;i++)	ans[i].clear();
		char str[24];
		getchar();
		for(int i = 1;i <= n;i++)
		{
			gets(str);
			trie.insert(str,i);
		}
		while(m--)
		{
			gets(str);
			memset(vis,0,sizeof(vis));
			trie.find(0,str);
			bool flag = false;
			for(int i = 1;i <= n;i++)
				if(vis[i])
				{
					if(flag)	printf(" ");
					printf("%d",i-1);
					flag = true;
				}
			if(!flag)		printf("Not match");
			puts("");
		}
	}
	return 0;
}


你可能感兴趣的:(字符串_Trie)