zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    OAuth认证介绍及腾讯微博OAuth认证示例
    Android PopupWindow介绍及实现菜单效果
    Android 输入法键盘和activity页面遮挡问题解决
    eclipse中android项目的编译过程分析
    Android Tween动画之RotateAnimation实现图片不停旋转
    eclipse 文件同步插件
    关于移动Web应用程序开发 HTML5、高性能JavaScript篇、Css的几篇较好博客
    Android 记录和恢复ListView滚动的位置的三种方法
    Apache的功能模块
    如何防止自己网站的图片被其他网站所盗用,从而导致自己网站流量的损失【apache篇】
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8051426.html
Copyright © 2011-2022 走看看