map[string] 访问元素时,如果没有元素string,会插入string,value默认初始化
map.count(string) 可能会意外判断有元素,用map[string].size()
#include <iostream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
typedef map<int, set<int> > IDS;
vector<string> Papers[128];
unordered_map<string, IDS > mmp;
int cnt = 0,outCnt = 0;
void GetKeyAndLine(string& temp, int nline, int id) {
string t = "";
//获取单词 并记录 单词出现的 文章id 和 行数 nline
for (int i = 0; i < temp.size(); ++i) {
//变成小写 搜索都是小写
if (isalpha(temp[i])) t += temp[i] | 0x20;
else {
if (t != "") {
mmp[t][id].insert(nline);
t = "";
}
}
}
if (t != "") {
mmp[t][id].insert(nline);
}
}
void OutOneKey(IDS& a) {
int id = 0,flag = 0;
for (auto it = a.begin(); it != a.end(); ++it) {
if (it->second.empty()) continue;
id = it->first;
for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
if (flag) { cout << "----------" << endl; flag = 0; }
cout << Papers[id][*it2] << endl;
outCnt++;
}
flag = 1;
}
}
//输出文章中包含 A 和 B 的行 从小到大输出行
int OutOnePaper(int id, set<int>& a, set<int>& b,int &flag) {
if (a.empty() && b.empty()) return 0;
set<int>::iterator first = a.begin();
set<int>::iterator second = b.begin();
//flag 换行标记
int t1 = 0, t2 = 0, t3 = 0;
while (first != a.end() || second != b.end()) {
if (first != a.end()) t1 = *first;
else t1 = 0xFFFF;
if (second != b.end()) t2 = *second;
else t2 = 0xFFFF;
//换行 标记换行结束 等待下次进入
if (flag) { cout << "----------" << endl; flag = 0; }
//当前t1是小的 输出t1行 寻找后继
if (t1 <= t2) {
cout << Papers[id][t1] << endl;
first++;
if (t1 == t2) second++;
}
else {
cout << Papers[id][t2] << endl;
second++;
}
//本轮输出的行数
t3++;
}
outCnt += t3;
return t3;
}
int main()
{
string tempStr, tempStr2;
vector<string> findKey;
int n;
//输入文章数
cin >> n; cin.ignore();
//输入文章
while (n) {
getline(cin, tempStr);
//文章结尾标记 跳转下一文章
if (tempStr == "**********") { n--; cnt++; continue; }
//处理行
GetKeyAndLine(tempStr, Papers[cnt].size(), cnt);
//保存行
Papers[cnt].emplace_back(tempStr);
}
//输入查询数量
cin >> n; cin.ignore();
while (n--) {
getline(cin, tempStr);
findKey.clear();tempStr2 = "";
//获取查询单词列表
for (int i = 0; i < tempStr.size(); ++i) {
if (isalpha(tempStr[i])) tempStr2 += tempStr[i] | 0x20;
else if (tempStr[i] == ' ') {
if (tempStr2.size()) {
findKey.emplace_back(tempStr2);
tempStr2 = "";
}
}
}
if(!tempStr2.empty()) findKey.emplace_back(tempStr2);
int flag = 0;
outCnt = 0;
//单个词 匹配
if (findKey.size() == 1) {
OutOneKey(mmp[findKey[0]]);
}
else if (findKey.size() == 2) {
//NOT 当前包含该单词的文章id列标 隐含了 插入{findKey[1],默认初始化值} 具体什么情况 还没搞清
IDS& a = mmp[findKey[1]];
for (int i = 0; i < cnt; ++i) {
//当前文章id 是否包含 单词
if (a[i].size()) continue;
if (outCnt++) cout << "----------" << endl;
//输出文章
for (int j = 0; j < Papers[i].size(); ++j) {
cout << Papers[i][j] << endl;
}
}
}
else if (findKey.size() == 3) {
if (findKey[1] == "and") {
//单词 分别包含的文章id
IDS& a = mmp[findKey[0]];
IDS& b = mmp[findKey[2]];
for (int i = 0; i < cnt; ++i) {
//同时包含
if (a[i].size() && b[i].size()) {
if (OutOnePaper(i, a[i], b[i], flag))flag = 1;
}
}
}
else {
//单词 分别包含的文章id
IDS& a = mmp[findKey[0]];
IDS& b = mmp[findKey[2]];
for (int i = 0; i < cnt; ++i) {
//只要有一个就输出当前文章
if (a[i].size() || b[i].size()) {
if (OutOnePaper(i, a[i], b[i], flag))flag = 1;
}
}
}
}
//
if (outCnt == 0) cout << "Sorry, I found nothing." << endl;
cout << "==========" << endl;
}
return 0;
}
本文介绍了一个文本检索系统的实现细节,包括如何构建倒排索引、处理查询请求及展示搜索结果等功能。通过对文本进行预处理,提取关键词,并利用哈希表和集合等数据结构,实现了高效的文本搜索。
268

被折叠的 条评论
为什么被折叠?



