zoukankan      html  css  js  c++  java
  • POJ 1816 Wild Words

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

    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
    题目大意:输入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
    ");
            }
            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("
    ");
            }
        }
        DeleteNode(pRoot);
        return 0;
    }
  • 相关阅读:
    长春区域赛总结
    HDU 4297 One and One Story (LCA>RMQ)
    SRM 578 div1
    开学,网赛,压力。。。
    HDU 4291 A Short problem
    最大密集子图(POJ 3155)
    ubuntu安装sunjdk1.6
    【转】容斥原理
    生成树计数问题(SPOJ 104 Highways)
    Tonelli–Shanks Algorithm 二次剩余系解法 (Ural 1132. Square Root)
  • 原文地址:https://www.cnblogs.com/lzmfywz/p/3257086.html
Copyright © 2011-2022 走看看