题意:给你一些模板串 再给你一些匹配串 问你每个匹配串分别能被那些模板串匹配
思路:由于模板串有100000个 所以一个一个匹配会超时 我们可以用字典树将这些模板串储存下来 查询时就会减少相同前缀的查找次数 然后就是暴搜了
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define REP( i, a, b ) for( int i = a; i < b; i++ )
struct Trie{
vector<int> id;
Trie *next[28];
Trie(){
id.clear();
REP(i, 0, 28) next[i] = NULL;
}
};
int n, m, Len;
char s[25];
vector<int> ans;
int Getid(char ch){
switch(ch){
case '?' : return 26;
case '*' : return 27;
default : return ch - 'a';
}
}
void CreatTrie(Trie *root, char *str, int _index){
Trie *p = root;
int len = strlen(str);
REP(i, 0, len){
int id = Getid(str[i]);
if(p -> next[id] == NULL) p -> next[id] = new Trie, printf("");
p = p -> next[id];
}
p -> id.push_back(_index);
}
void DFS(Trie *root, int index){
if(root -> next[27]){
REP(i, index, Len + 1) DFS(root -> next[27], i);
}
if(index == Len){
REP(i, 0, root -> id.size()) ans.push_back(root -> id[i]);
return;
}
if(root ->next[Getid(s[index])]) DFS(root -> next[Getid(s[index])], index + 1);
if(root -> next[26]) DFS(root -> next[26], index + 1);
}
void DelTrie(Trie *root){
if(root == NULL) return;
REP(i, 0, 28) DelTrie(root -> next[i]);
delete root;
}
void solve(){
char str[25];
Trie *root = new Trie;
REP(i, 0, n){
scanf("%s", str);
CreatTrie(root, str, i);
}
REP(i, 0, m){
scanf("%s", s);
Len = strlen(s);
ans.clear();
DFS(root, 0);
if(ans.size()){
sort(ans.begin(), ans.end());
ans.resize(unique(ans.begin(), ans.end()) - ans.begin());
bool flag = false;
REP(i, 0, ans.size()){
if(flag) printf(" ");
printf("%d", ans[i]);
flag = true;
}
printf("\n");
}
else printf("Not match\n");
}
DelTrie(root);
}
int main()
{
//freopen("in.txt", "r", stdin);
while(~scanf("%d%d", &n, &m)) solve();
return 0;
}

本文介绍了一种利用字典树优化模板串匹配的方法,针对大量模板串与目标串匹配的问题,通过构建字典树减少重复计算,提高匹配效率。
805

被折叠的 条评论
为什么被折叠?



