• poj1816 Wild Words


    Wild Words
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 5567   Accepted: 1475

    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
    

    Source

    大致题意:给n个模式串和m个字符串,*可以代表任意字符串(空串),?只能代表一个特定字符,问每个字符串有哪些模式串与它匹配?
    分析:题目给了很多模式串,将它们放在trie树上.因为可能会有相同的模式串,所以需要记录一下当前点为多少个模式串的终点,利用vector或者邻接表都可以.匹配的话利用dfs,一个指针在trie上走,另一个在字符串上走,每次匹配有3种可能:1.直接走当前字符的下一位. 2.走?的一位. 3.走*的一位.对于?和*,用特殊的数字26,27存在trie中.*的转移比较麻烦,它有可能只占一个字符,有可能是空串,也有可能占很多串,这样就要分三种情况搜下去.对于第三种情况,由于trie存的是边,并不知道当前点是不是由*转移过来的,必须要在trie树中表示每个点的字符.需要注意的是搜索的终点并不是字符串的完结,而是trie跳到了终点,因为可能模式串末尾有一大堆**这么一说非常抽象,看代码可能更容易理解一些.
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    const int maxn = 100001;
    
    using namespace std;
    int n, m, len, tot = 1, head[maxn], nextt[maxn], to[maxn], tott = 1;
    char s[maxn], s2[maxn];
    bool flag[maxn], can;
    
    vector <int> E[maxn];
    
    struct node
    {
        char ch;
        int tr[30];
        void clear(char c)
        {
            ch = c;
            memset(tr, 0, sizeof(tr));
        }
    }e[maxn * 10];
    
    int zhuanhuan(char x)
    {
        if (x == '?')
            return 26;
        if (x == '*')
            return 27;
        else
            return x - 'a';
    }
    
    void add(int x, int y)
    {
        to[tott] = y;
        nextt[tott] = head[x];
        head[x] = tott++;
    }
    
    void insert(char *ss, int id)
    {
        int u = 1;
        len = strlen(ss + 1);
        for (int i = 1; i <= len; i++)
        {
            int t = zhuanhuan(ss[i]);
            if (!e[u].tr[t])
            {
                e[u].tr[t] = ++tot;
                e[tot].clear(ss[i]);
            }
            u = e[u].tr[t];
        }
        add(u, id); //邻接表
    }
    
    void dfs(int dep, int u)
    {
        if (dep == len + 1)
        {
            for (int i = head[u]; i; i = nextt[i])
            {
                int v = to[i];
                can = flag[v] = 1;
            }
            if (e[u].tr[27])   //trie没走完
                dfs(dep, e[u].tr[27]);
            return;
        }
        int temp = zhuanhuan(s2[dep]);
        if (e[u].tr[temp])
            dfs(dep + 1, e[u].tr[temp]);
        if (e[u].tr[26])
            dfs(dep + 1, e[u].tr[26]);
        if (e[u].tr[27])
        {
            dfs(dep + 1, e[u].tr[27]);
            dfs(dep, e[u].tr[27]);
        }
        if (e[u].ch == '*') //如果当前点是*
            dfs(dep + 1, u);
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
        {
            scanf("%s", s + 1);
            insert(s, i - 1);
        }
        while (m--)
        {
            can = false;
            scanf("%s", s2 + 1);
            len = strlen(s2 + 1);
            memset(flag, false, sizeof(flag));
            dfs(1, 1);
            if (!can)
            {
                printf("Not match
    ");
                continue;
            }
            for (int i = 0; i < n; i++)
                if (flag[i])
                    printf("%d ", i);
            printf("
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    跨平台这件事儿
    BTrace : Java 线上问题排查神器
    Spring 实现自定义 bean 的扩展
    运用计划缓冲的建议
    查询计划Hash和查询Hash
    执行计划的重用
    执行计划组件、组件、老化
    执行计划的生成
    SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 <第一篇>
    SQL Server执行计划的理解
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8051426.html
Copyright © 2020-2023  润新知