POJ 1816 Wild Words

/*

http://acm.pku.edu.cn/JudgeOnline/problem?id=1816
trie树下的DFS, 感觉非常好的一道题,能说明很多问题
*/

#include <iostream>
#include <algorithm>
#define MAX_M 100000
using namespace std;

//输入的pattern数以及待匹配的单词数
int pNum, strNum;
char temp[30];
//当前单词匹配的模式ID以及匹配的模式数
int  match[MAX_M + 1], matchNum = 0;

//类似于邻接表,当有两个模式串巷同时进行记录和匹配
struct pN
{
    //模式串的ID
    int id;
    //邻接模式串
    pN *next;
};
//用于对匹配的模式串ID进行排序
bool compare(int a, int b)
{
    if(a >= b)
        return true;
}
//得到当前字符c在trie树next表中的index下标
int getIndex(char c)
{
    int pos = 0;
    if(c == '?') pos = 26;
    else if(c == '*') pos = 27;
    else pos = c - 'a';
    return pos;
}
//trie树节点的定义
struct trieNode
{
    int id;
    //0-25表示a-z 26个小写字母,26表示'?',27表示'*'
    trieNode *next[28];
    pN *rep; //记录重复的pattern
    trieNode()
    {
        //初始化
        for(int i = 0; i < 28; i++)
            next[i] = NULL;
        id = 0;
        rep = NULL;
    }
};
//trie树的根
trieNode *root;
//向trie树中插入模式串pattern, id为id
void insert(char pattern[], int id)
{
    char c;
    int i, pos, len = strlen(pattern);
    if(!root) root = new trieNode();
    trieNode *curNode = root;
    for(i = 0; i < len; i++)
    {
        c = pattern[i];
        pos = getIndex(c);
        if(!curNode->next[pos])
            curNode->next[pos] = new trieNode();
        curNode = curNode->next[pos];
    }
    //记录ID,如果已经出现过此匹配串则需要添加邻接信息
    if(curNode->id == 0)
        curNode->id = id;
    else
    {
        pN *newPN = new pN();
        newPN->id = id;
        newPN->next = curNode->rep;
        curNode->rep = newPN;
    }
}

//待匹配单词为temp,当前匹配到的位置是pos,当前匹配到的结点是curNode
void trieDFS(char * const & temp, int pos, trieNode *curNode)
{
    //当整个单词扫描完,不能立即返回,因为单词后面还可以接*号
    if(pos >= strlen(temp))
    {
        //当前结点是一个有效的模式串
        if(curNode->id != 0)
        {
            //标记匹配信息
            match[matchNum++] = curNode->id;
            pN *rpn = curNode->rep;
            while(rpn)
            {
                match[matchNum++] = rpn->id;
                rpn = rpn->next;
            }
        }
    }
    //若当前单词还没有扫描完,则继续扫描
    if(pos < strlen(temp))
    {
        char c;
        c = temp[pos];
        //直接匹配当前字母
        int index = getIndex(c);
        if(curNode->next[index])
            trieDFS(temp, pos + 1, curNode->next[index]);
        //匹配?
        if(curNode->next[26])
            trieDFS(temp, pos + 1, curNode->next[26]);
    }
    //匹配*
    if(curNode->next[27])
    {
        int p;
        for(p = pos; p <= strlen(temp); p++)
            trieDFS(temp, p, curNode->next[27]);
    }
}
int main()
{
    int i, j;
    cin>>pNum>>strNum;
    for(i = 0; i < pNum; i++)
    {
        scanf("%s", temp);
        insert(temp, i + 1);
    }
    for(i = 0; i < strNum; i++)
    {
        cin>>temp;
        matchNum = 0;
        trieDFS(temp, 0, root);
        if(matchNum == 0)
            printf("Not match/n");
        else
        {
            sort(match, match + matchNum);
            for(j = 0; j < matchNum - 1; j++)
            {
                if(match[j] != match[j + 1])
                    printf("%d ", match[j] - 1);
            }
            printf("%d/n", match[matchNum  - 1] - 1);
        }
    }
    return 0;
}

你可能感兴趣的:(c,struct,null,insert)