// 12_27.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<iostream> #include<memory> #include<string> #include<vector> #include<fstream> #include<sstream> #include<map> #include<set> using namespace std; //提前声明类QueryResult,在书中说必须提前声明,然而vs2015中 //仅声明友元类亦可 class QueryResult; class TextQuery { //友元类的声明 friend class QueryResult; public: //构造函数 TextQuery(ifstream &is); //返回查询的结果 QueryResult query(string s); private: //用智能指针来保存数据,实现共享 shared_ptr<vector<string>> vecPtr; shared_ptr<map<string, set<unsigned>>> mapPtr; }; //TextQuery的构造函数 TextQuery::TextQuery(ifstream &is) { //用来暂存每一行的字符串 string word; //记录行数 unsigned lineNum = 0; //对两个智能指针进行值初始化 vecPtr = shared_ptr<vector<string>>(new vector<string>()); mapPtr = shared_ptr<map<string, set<unsigned>>>(new map<string, set<unsigned>>()); while (getline(is, word)) { //将每一行保存在类中 vecPtr->push_back(word); istringstream iss(word); string str; while (iss >> str) { //将单词所在的行数记录下来 (*mapPtr)[str].insert(lineNum); } ++lineNum; } } class QueryResult { public: //QueryResult的构造函数,vecPtr实现共享 QueryResult(TextQuery &tq, string &s) :vecPtr(tq.vecPtr) { //mapPtr指针的值初始化 mapPtr = shared_ptr<map<string, set<unsigned>>>(new map<string, set<unsigned>>()); //将要查询的单词的结果保存下来 mapPtr->insert(pair<string, set<unsigned>>(s, (*tq.mapPtr)[s])); } //有缘函数,实现输出 friend ostream& print(ostream&,const QueryResult &qr); private: shared_ptr<vector<string>> vecPtr; shared_ptr<map<string, set<unsigned>>> mapPtr; }; //QueryResult的友元函数,实现输出 ostream& print(ostream &os,const QueryResult &qr) { //输出这个单词出现了多少次 os << (*qr.mapPtr).cbegin()->first << " occurs " << (*qr.mapPtr).cbegin()->second.size() << ((*qr.mapPtr).cbegin()->second.size() > 1 ? "times" : "time") << endl; //输出单词所在的行数,和这一行的字符串 for (auto &e : qr.mapPtr->cbegin()->second) os << "(line " << e << " ) " << (*qr.vecPtr)[e] << endl; return os; } //实现查询的函数 QueryResult TextQuery::query(string s) { return QueryResult(*this, s); } void runQueries(ifstream &infile) { TextQuery tq(infile); while (true) { cout << "enter 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 ifs("D:\\file\\12_27.txt"); if (!ifs) { cerr << "open file failed!" << endl; exit(-1); } runQueries(ifs); return 0; }