题目大意:简易版的搜索,只有4种情况, 查询单词a,查询a and b,查询a or b,查询not a,输出相应的结果,注意a and b是同一篇文章里的有a的内容和有b的内容,a和b不一定需要在同一行。
思考:题意即思路。
只是我写的比较麻烦。。
map<string,set<Pair> > word 存放word在哪些文章的行出现过,因为set可以自己排序,所以用了set。
vector<string > page[maxn] 存放文章的内容
后面的几个set是为了操作准备的。
处理 or not 和直接查单词都比较容易。
最坑的是a and b
我的想法是首先找出a和b公用的文章, 然后把a和b在公用文章中的行都推进一个set<Pair> 容器里,
因为set内部直接是有序的,所以先出来的一定是按照输入的顺序。
输出的时候记得卡一下同一篇文章不输出'----------'
提示:1. ———-是10个。
2. 无脑交了几发PE的,最后发现是读完n值读了一个‘\n’….所以有多的转行,用getchar()读取回车。
#include <bits/stdc++.h>
using namespace std;
#define Pair pair<int,int>
#define maxn 1005
map<string,set<Pair> > word;
vector<string> page[maxn];
set<Pair> aorb;
set<int> opnot,joina,joinb;
int n;
int inser(string w,int i,int j)
{
set<Pair> temp;
if(word.count(w) == 0)
{
temp.insert(Pair(i,j));
word[w] = temp;
}
else
word[w].insert(Pair(i,j));
return 0;
}
int standard(string w,int i,int j) //将字符标准化
{
string m = w;
for(int i = 0; i < m.size(); i++)
{
if(!isupper(m[i]) && !islower(m[i]))
m[i] = ' ';
if(isupper(m[i]))
m[i] = m[i] + ('a' - 'A');
}
string s;
stringstream ss;
ss<<m;
while(ss >> s)
inser(s,i,j);
return 0;
}
int dealdata() //输入数据
{
for(int i = 0; i < n; i++)
for(int j = 0; j < page[i].size(); j++)
{
string temp = page[i][j];
string w;
stringstream ss;
ss << temp;
while(ss >> w)
standard(w,i,j);
}
}
int solve() //输入查询
{
int k;
scanf("%d",&k);
getchar();
while(k--)
{
int flag = 0;
string temp;
aorb.clear(); opnot.clear(); joina.clear(); joinb.clear();
getline(cin,temp);
if(temp.find("AND") != string :: npos)
{
string a,b;
a = temp.substr(0,temp.find_first_of(' '));
b = temp.substr(temp.find_last_of(' ')+1);
int last = -1;
if(word.count(a) == 0 || word.count(b) == 0)
flag = 0;
else
{
for(auto it : word[a])
joina.insert(it.first);
for(auto it : word[b])
joinb.insert(it.first);
for(int i = 0; i < n ; i++)
{
if(joina.count(i) && joinb.count(i))
opnot.insert(i);
}
for(auto it : word[a])
if(opnot.count(it.first))
aorb.insert(it);
for(auto it : word[b])
if(opnot.count(it.first))
aorb.insert(it);
int num = 0;int last = -1;
for(auto it : aorb)
{
flag = 1;
int p = it.first , l = it.second;
if(p != last && num != 0) cout<<"----------\n";
cout<<page[p][l]<<endl;
num++;
last = p;
}
}
}
else if(temp.find("OR") != string :: npos)
{
string a,b;
a = temp.substr(0,temp.find_first_of(' '));
b = temp.substr(temp.find_last_of(' ')+1);
if(word.count(a) == 0 && word.count(b) == 0)
flag = 0;
else
{
if(word.count(a) != 0)
for(auto it : word[a])
aorb.insert(it);
if(word.count(b) != 0)
for(auto it : word[b])
aorb.insert(it);
if(aorb.empty()) flag = 0;
else
{
int num = 0; int last = -1;
for(auto it : aorb)
{
flag = 1;
int p = it.first, l = it.second;
if(num != 0 && last != p)
cout<<"----------\n";
num++;
cout<<page[p][l]<<endl;
last = p;
}
}
}
}
else if(temp.find("NOT") != string :: npos)
{
string w = temp.substr(temp.find(" ")+1);
if(word.count(w) == 0)
flag = 1;
else
{
for(auto it : word[w])
opnot.insert(it.first);
}
int num = 0;
for(int i = 0 ; i < n ;i ++)
{
if(opnot.count(i) == 1) continue;
flag = 1;
if(num != 0)
cout<<"----------\n";
num++;
for(int j = 0; j < page[i].size(); j++)
cout<<page[i][j]<<endl;
}
}
else
{
if(word.count(temp) == 0)
flag = 0;
else
{
int num = 0; int last = -1;
for(auto it : word[temp])
{
int a = it.first, b = it.second;
flag = 1;
if(num != 0 && a != last)
cout<<"----------\n";
num++;
last = a;
cout<<page[a][b]<<endl;
}
}
}
if(!flag)
cout<<"Sorry, I found nothing.\n";
cout<<"=========="<<endl;
}
}
int main()
{
//freopen("D://in.txt","r",stdin);
scanf("%d",&n);
getchar();
for(int i = 0; i < n ; i++)
{
string temp;
while(getline(cin,temp))
{
if(temp == "**********")
break;
else page[i].push_back(temp);
}
}
dealdata();
solve();
return 0;
}