Searching the Web UVA - 1597

Posted jionkitten

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Searching the Web UVA - 1597相关的知识,希望对你有一定的参考价值。

链接:https://vjudge.net/problem/UVA-1597#author=0

这题写了我一个晚上,然后debug了一个早上。。

最主要就是AND那一部分,一开始用了一个很奇怪的方法实现,就是利用set递增的性质,设置一个cur变量保存现在遍历到的文章下标的最大值,然后检查s1和s2能否取到,cur每次取当前s1和s2的文章下标最大值。中间实现的时候也出了点bug,没有在遍历到末尾的时候跳出循环。然而这不是重点。。重点在于cur不一定取到,也就是可以跳过cur取一个更大的值, 这个时候就与cur的定义就产生了矛盾。如果要在这基础上修改的话估计就是把不等号改为小于号,然而我已经懒得写了,用最原始的方法过了(不过还是出了点bugQAQ,忘记了可重性)。有些时候没办法就换个方法写,像这种情况以我的智商真的很难想到,如果不假想构造模拟数据的话。经验的话就是明确关键变量的定义,就是有特殊性质的那些,然后看后面的程序有没有违反或者可能破坏这个定义,不过这真的很难想到。。模拟数据大法好

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
#include <sstream>
#include <cctype>
#include <algorithm>
#include <bitset>
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
//#define fre
//#define DEBUG
using namespace std;
struct Pos
{
    int d, l;
    Pos(int d, int l): d(d), l(l) {}
    bool operator < (const Pos& b) const
    {
        if (d == b.d) return l < b.l;
        else return d < b.d;
    }
};
map<string, set<Pos> > lib;
string doc[105][1505];

string stdize(string s)
{
    for (char& c : s)
    {
        if (!isalpha(c)) c =  ; //这里没看清题意,题目要求忽略所有非字母字符,英语不好哭了
        else c = tolower(c);
    }
    return s;
}

int main()
{
    #ifdef fre
    freopen("in.in", "r", stdin);
    freopen("out.txt", "w", stdout);
    #endif
    set<Pos> tmp, s1, s2;
    int d, l, n, cur;
    bool fir = true;
    string word, line, a, b, c;
    char buf[3];
    bitset<105> bit;
    int com[105];
    scanf("%d", &d);
    fgets(buf, 3, stdin);
    for (int i = 0; i < d; ++i)
    {
        l = 0;
        while (getline(cin, doc[i][l]) && doc[i][l][0] != *)
        {
            stringstream ss(stdize(doc[i][l]));
            while (ss >> word)
            {
                lib[word].insert(Pos(i, l));
                /*#ifdef DEBUG
                cout << word << " : " << endl;
                cout << i << "-" << l << endl;
                #endif*/
            }
            ++l;
            //fgets(buf, 3, stdin);
        }
    }
    scanf("%d", &n);
    fgets(buf, 3, stdin); //在标准输入后记得吞换行符
    while (n-- && getline(cin, line))
    {
        fir = true;
        stringstream ss(line);
        ss >> a;
        if (ss >> b)
        {
            if (ss >> c)
            {
                tmp.clear();
                s1 = lib[stdize(a)];
                s2 = lib[stdize(c)];
                /*#ifdef DEBUG
                cout << a << endl;
                for (auto& i : s1) cout << i.d << " " << i.l << endl;
                cout<< c << endl;
                for (auto& i : s2) cout << i.d << " " << i.l << endl;
                #endif */
                //万恶之源,就是这一段
                if (b[0] == A)
                {
                    memset(com, 0, sizeof(com));
                    for (auto& i : s1) com[i.d] = 1;
                    for (auto& i : s2)
                    {
                        if (com[i.d] == 1) com[i.d] = 2;
                    }
                    for (auto& i : s1) 
                    {
                        if (com[i.d] == 2) tmp.insert(i);
                    }
                    for (auto& i : s2) 
                    {
                        if (com[i.d] == 2) tmp.insert(i);
                    }
                }
                else set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(tmp, tmp.begin()));
                for (auto& i : tmp)
                {
                    if (fir) cur = i.d, fir = false;
                    else if (i.d > cur) cout << "----------
", cur = i.d;
                    cout << doc[i.d][i.l] << 
;
                }
            }
            else 
            {
                bit.set();
                for (auto& i : lib[stdize(b)]) bit[i.d] = 0;
                for (int i = 0; i < d; ++i)
                {
                    if (bit[i])
                    {
                        if (fir) fir = false;
                        else cout << "----------
";
                        int j = 0;
                        while (doc[i][j][0] != *) cout << doc[i][j++] << endl;
                    }
                }
            }
        }
        else
        {
            for (auto& i : lib[stdize(a)])
            {
                if (fir) cur = i.d, fir = false;
                else if (i.d > cur) cout << "----------
", cur = i.d;
                cout << doc[i.d][i.l] << 
;
            }
        }
        if (fir) cout << "Sorry, I found nothing.
";
        cout << "==========
";
        //fgets(buf, 3, stdin);
    }
}

 

以上是关于Searching the Web UVA - 1597的主要内容,如果未能解决你的问题,请参考以下文章

UVA 1597 Searching the Web

ZOJ3228 Searching the String(AC自动机)

AC自动机---Searching the String

ZOJ - 3228 Searching the String (AC自己主动机)

ZOJ Searching the String(match指针暴力跳fail)

ZOJ3228 Searching the String (AC自动机)