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;
}
相關文章
相關標籤/搜索