POJ - 1816 Wild Words (模糊状态下字典树匹配)

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

            简单来说就是字典树上进行dfs。这里注意的是,最后保存答案的时候用set是会tle的~~

#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
const int N = 1e6 + 5;
int nex[N][30];
int tot = 0; vector<int>G[N];
int Hash(char x) {
	if (x == '?')
		return 26;
	if (x == '*')
		return 27;
	return  x - 'a';
}
void insert(string m, int id) {
	int len = m.length();
	int root = 0;
	for (int i = 0; i < len; i++) {
		int id = Hash(m[i]);
		if (nex[root][id] == 0)
			nex[root][id] = ++tot;
		root = nex[root][id];
	}
	G[root].push_back(id);
}
vector<int>ans;
void dfs(string m, int pos, int root) {
	if (pos == m.length()) {
		if (nex[root][27] != 0) {
			for (int i = pos; i <= m.length(); i++) {
				dfs(m, i, nex[root][27]);
			}
		}
		for (int i = 0; i < G[root].size(); i++) {
			ans.push_back(G[root][i]);
		}
		return;
	}
	if (nex[root][Hash(m[pos])] != 0) {
		dfs(m, pos + 1, nex[root][Hash(m[pos])]);
	}
	if (nex[root][26] != 0) {
		dfs(m, pos + 1, nex[root][26]);
	}
	if (nex[root][27] != 0) {
		for (int i = pos; i <= m.length(); i++) {
			dfs(m, i, nex[root][27]);
		}
	}
}
void finstr(string m) {
	ans.clear();
	dfs(m, 0, 0);
	if (ans.size() == 0) {
		cout << "Not match\n";
		return;
	}
	sort(ans.begin(), ans.end()); int sum = 0;
	for (int i = 0; i < ans.size(); i++) {
		if (i == 0 || ans[i] != ans[i - 1]) {
			if (sum != 0)cout << " ";
			cout << ans[i];
			sum++;
		}
	}
	cout << "\n";
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		string t; cin >> t;
		insert(t, i - 1);
	}
	for (int i = 0; i < m; i++) {
		string t; cin >> t;
		finstr(t);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值