nes->begin()));
return QueryResult(rep(), ret_lines, left.get_file());
}
QueryResult OrQuery::eva l(const TextQuery& text)const{
//通过Query成员lhs,rhs进行虚调用
//调用eva l返回每个对象的QueryResult
auto right = rhs.eva l(text);
auto left = lhs.eva l(text);
//将左侧运算对象的行号拷贝到结果set中
auto ret_lines =
std::make_shared<std::set<line_no>>(left.begin(), left.end());
//插入右侧运算对象所得的行号
ret_lines->insert(right.begin(), right.end());
//返回一个新的QueryResult,它表示lhs和rhs的并集
return QueryResult(rep(), ret_lines, right.get_file());
}
QueryResult.h
#ifndef __QUERYRESULT_H__
#define __QUERYRESULT_H__
#include <iostream>
#include <set>
#include <vector>
#include <string>
#include <memory>
class QueryResult{
friend std::ostream& print(std::ostream&, const QueryResult&);
public:
using line_no = std::vector<std::string>::size_type;
using Iter = std::set<line_no>::iterator;
QueryResult(std::string s, std::shared_ptr<std::set<line_no>> p,
std::shared_ptr<std::vector<std::string>> f):
sought(s), lines(p), file(f){}
Iter begin() const {return lines->begin();}
Iter end() const {return lines->end();}
std::shared_ptr<std::vector<std::string>> get_file() const{
return file;
}
private:
std::string sought;//查询的单词
std::shared_ptr<std::set<line_no>> lines;//出现的行号
std::shared_ptr<std::vector<std::string>> file;
};
//QueryResult类的友元声明
std::ostream& print(std::ostream&, const QueryResult&);
#endif
TextQuery.h
#ifndef __TEXTQUERY_H__
#define __TEXTQUERY_H__
#include "QueryResult.h"
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <vector>
#include <string>
#include <memory>
using namespace std;
class TextQuery{
public:
using line_no = std::vector<std::string>::size_type;
TextQuery(ifstream& is);
QueryResult query(const std::string &sought) const;
private:
std::shared_ptr<std::vector<std::string>> file;
std::map<std::string, std::shared_ptr<std::set<line_no>>> wm;
};
#endif
TextQuery.cpp
#include "TextQuery.h"
using namespace std;
TextQuery::TextQuery(ifstream& is) : file(new vector<string>){
string text;
while(getline(is, text)){//读文件的每一行
file->push_back(text);
int n = file->size() - 1;//当前行号
istringstream line(text);//将行文本分解为单词
string word;
while(line >> word){
//非常重要,必须用引用,要不然就会拷贝一个新的set给lines,不是原来的
auto &lines = wm[word];//lines是shared_ptr
if(!lines)
lines.reset(new set<line_no>);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const string &sought) const{
//如果没有找到sought,返回指向此set的一个智能指针
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto ret = wm.find(sought);
if(ret == wm.end()){
return QueryResult(sought, nodata, file);//没有找到
}
else{
return QueryResult(sought, ret->second, file);
}
}
main.cpp
#include "Query.h"
//QueryResult的友元函数
ostream& print(ostream& os, const QueryResult& qr){
os << qr.sought << " 出现了:" &