文本查询类的定义
第12章最后的文本查询小程序的编写,看起来很简单,其实也很简单,本来想着看看得了,比这复杂的不知道编写了多少,但是还是编写了一下,其中还是有坑需要注意:
- 注意引用&,一不小心忘了写就得慢慢调试看看咯
- 其他没有了
TextQuery
通过传入的文件路径初始化此类的对象,初始化时完成以下工作:
- 读取文件中的一行,存入指向vector<string>类型的智能指针file中
- 读取每一个单词,存入map<string,shared_ptr<set<int>>> wm中,其中key为单词,value中此单词所在的行数,每个单词在每行只记录一次。
- 查询方法query,根据给定的单词,通过map对象wm,找出单词出现的所有行,并根据单词(string)、行(map的value,shared_ptr<set<int>>类型)、文件内容(vector<string>)这三个对象构造QueryResult对象。
QueryResult
- 包含构造此类型对象的三个参数,主要内容其实就是一个输出函数print
#include <istream> #include<vector> #include<string> #include<memory> #include<map> #include<set> #include<sstream> using namespace std; using line_no = vector<string>::size_type; class QueryResult { friend std::ostream& print(ostream&, const QueryResult&); public: QueryResult(string s, shared_ptr<set<line_no>>p, shared_ptr<vector<string>> f) :sought(s), lines(p), file(f) { } private: string sought; shared_ptr<set<line_no>> lines; shared_ptr<vector<string> > file; }; class TextQuery { public: TextQuery(istream& file_stream) { file= make_shared<vector<string>>(); string text; while (getline(file_stream, text)) { file->push_back(text); istringstream iss(text); string word; while (iss >> word) { auto& lines = wm[word]; if (!lines) lines = make_shared<set<line_no>>(); lines->insert(file->size() - 1); } } } ~TextQuery() { } QueryResult query(const string &sought)const { static shared_ptr<set<line_no>> nodata(new set<line_no>); auto loc = wm.find(sought); if (loc != wm.end()) return QueryResult(sought, loc->second, file); else return QueryResult(sought, nodata, file); } private : shared_ptr<vector<string> > file; map<string, shared_ptr<set<line_no>>> wm; }; ostream& print(ostream&os, const QueryResult &qr) { os << qr.sought << " occurs " << qr.lines->size() << " " << ((qr.lines->size())==1? "time": "times") << endl; for (auto num : *qr.lines) { os << "\t(line " << num + 1 << ")" << qr.file->at(num) << endl; } return os; } void runQueries(ifstream &infile) { TextQuery tq(infile); while (true) { cout << "enter the word to look for, or q to quit:"; string s; if (!(cin >> s) || s == "q") break; print(cout, tq.query(s)) << endl; } } int main() { ifstream file("C:\...\123.txt"); runQueries(file); file.close(); }