1. 程式人生 > >poj 1816 Wild Words

poj 1816 Wild Words

name pattern stream cee and trie order ber clas

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

Source

POJ Monthly 給出一些pattern,然後給出一些子串,找出與之可以匹配的pattern的下標,問好必須匹配一個字符,星號可以匹配任意個字符(包括0),坑的是可能有重復的pattern,也就是說每個pattern可以對應多個下標。先用字典樹記錄pattern,然後標記每個結尾,下標指向相應結尾,check的時候,如果滿足,就把結尾的ans標記為true,最後判斷哪個下標對應的結尾是true,就輸出。 代碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAX 600005
using namespace std;
int trie[MAX][28];
bool flag[MAX];
int to[100000];
int pos,n,m;
bool ans[MAX];
int Insert(char *s) {
    int i = 0,c = 0;
    while(s[i]) {
        int d = isalpha(s[i]) ? s[i] - a : s[i] == ? ? 26 : 27;
        if(!trie[c][d]) trie[c][d] = ++ pos;
        c = trie[c][d];
        i ++;
    }
    flag[c] = true;
    return c;
}
void check(char *s,int si,int c) {
    if(si == strlen(s) && flag[c]) {
        ans[c] = true;
    }
    int d = s[si] - a;
    if(trie[c][d]) {
        check(s,si + 1,trie[c][d]);
    }
    if(trie[c][26]) {
        check(s,si + 1,trie[c][26]);
    }
    if(trie[c][27]) {
        int sj = si;
        while(sj <= strlen(s)) {
            check(s,sj,trie[c][27]);
            sj ++;
        }
    }
}
int main() {
    char s[30];
    scanf("%d%d",&n,&m);
    for(int i = 0;i < n;i ++) {
        scanf("%s",s);
        to[i] = Insert(s);
    }
    for(int i = 0;i < m;i ++) {
        scanf("%s",s);
        memset(ans,false,sizeof(ans));
        int match = 0;
        check(s,0,0);
        for(int j = 0;j < n;j ++) {
            if(ans[to[j]]) {
                printf("%d ",j);
                match ++;
            }
        }
        if(!match)printf("Not match");
        putchar(\n);
    }
}

poj 1816 Wild Words