POJ 1816 Wild Words

Wild Words
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 4412   Accepted: 1149

Descriptionnode

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. 

Inputios

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. 

Outputthis

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 Inputspa

5 4
t*
?h*s
??e*
*s
?*e
this
the
an
is

Sample Outputcode

0 1 3 
0 2 4 
Not match
3
题目大意:输入N,M而后输入N行字符串,由'?','*'和26个小写字母组成,'?'表明任意一个小写字母,'*'表明0个或者多个小写字母,紧接着输入M行字符串,问每行字符串和前面N行字符串中哪些是等价的。
解题方法:经典的DFS+字典树,先创建创建一颗字典树,而后用DFS进行搜索。
#include <stdio.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;

int ans[100005];
int nCount;
char str[25];

typedef struct node
{
    vector <int> id;
    node *next[28];
    node()
    {
        id.clear();
        memset(next, 0, sizeof(next));
    }
    ~node()
    {
        id.clear();
    }
}TreeNode;

int GetIndex(char ch)
{
    switch(ch)
    {
    case '?':
            return 26;
    case '*':
        return 27;
    default:
        return ch - 'a';
    }
}

//创建字典树
void Insert(TreeNode *pRoot, char pstr[], int id)
{
    int nLen = strlen(pstr);
    TreeNode *p = pRoot;
    for (int i = 0; i < nLen; i++)
    {
        int index = GetIndex(pstr[i]);
        if (p->next[index] == NULL)
        {
            p->next[index] = new TreeNode;
        }
        p = p->next[index];
    }
    p->id.push_back(id);//每一个单词的结尾保存该单词的编号
}

void DFS(TreeNode *pRoot, int index)
{
    if (pRoot->next[27] != NULL)
    {
        //忽略掉'*',即'*'表明0个字母
        DFS(pRoot->next[27], index);
    }
    if (index == strlen(str))
    {
        //若是遍历到了最后一个字母,则把编号加进去
        for (int i = 0; i < pRoot->id.size(); i++)
        {
            ans[nCount++] = pRoot->id[i];
        }
        return;
    }
    //若是字典树和字符串当前都是字母,则同时跳过该字母
    if (pRoot->next[GetIndex(str[index])] != NULL)
    {
        DFS(pRoot->next[GetIndex(str[index])], index + 1);
    }
    if (pRoot->next[26] != NULL)
    {
        //若是字典树中当前是'?',直接跳过
        DFS(pRoot->next[26], index + 1);
    }
    if (pRoot->next[27] != NULL)
    {
        //若是字典树中当前是‘*’,则让‘*’表明多个字符
        for (int i = index; i < strlen(str); i++)
        {
            DFS(pRoot->next[27], i + 1);
        }
    }
}

void DeleteNode(TreeNode *pRoot)
{
    if (pRoot != NULL)
    {
        for (int i = 0; i < 28; i++)
        {
            DeleteNode(pRoot->next[i]);
        }
    }
    delete pRoot;
}

int main()
{
    int N, M, nID = 0;
    scanf("%d%d", &N, &M);
    TreeNode *pRoot = new TreeNode;
    for (int i = 0; i < N; i++)
    {
        scanf("%s", str);
        Insert(pRoot, str, nID++);
    }
    for (int i = 0; i < M; i++)
    {
        nCount = 0;
        scanf("%s", str);
        DFS(pRoot, 0);
        if (nCount == 0)
        {
            printf("Not match\n");
        }
        else
        {
            sort(ans, ans + nCount);
            printf("%d", ans[0]);
            for (int j = 1; j < nCount; j++)
            {
                if (ans[j - 1] != ans[j])
                {
                    printf(" %d", ans[j]);
                }
            }
            printf("\n");
        }
    }
    DeleteNode(pRoot);
    return 0;
}
相关文章
相关标签/搜索