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;
    }
  • 相关阅读:
    C-5 猜数字游戏
    J-8 面向对象
    C-4 一个标准的学生类的代码及测试
    J-7 面向对象
    C-3 this的使用
    J-6 面向对象
    ArcEngine关于单位转换示例
    Arcglobe三维信息系统开发常见问题
    安装arcgis server 10.2遇到的问题总结
    使用Arcglobe 10与3dmax建立三维城市
  • 原文地址:https://www.cnblogs.com/lzmfywz/p/3257086.html
Copyright © 2011-2022 走看看