1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| class QueryResult; class TextQuery { public: friend QueryResult; using line_no = vector<string>::size_type; TextQuery(ifstream&); QueryResult query(const string&) const; private: shared_ptr<vector<string>> file; map<string, shared_ptr<set<line_no>>>wm; }; 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) { auto& lines = wm[word]; if (!lines) lines.reset(new set<line_no>); lines->insert(n); } } } class QueryResult { friend ostream& print(ostream&, const QueryResult&); public: QueryResult(string s,shared_ptr<set<TextQuery::line_no>>p,shared_ptr<vector<string>> f):sought(s),lines(p),file(f){}
private: string sought; shared_ptr<set<TextQuery::line_no>>lines; shared_ptr<vector<string>> file; }; QueryResult TextQuery::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, nodata, file); else return QueryResult(sought, loc->second, file); } ostream& print(ostream& os, const QueryResult& qr) { os << qr.sought << " occurs " << qr.lines->size() << " " << endl; for (auto num : *qr.lines) { os << "\y(line " << num + 1 << ")" << *(qr.file->begin() + num) << endl; } return os; } 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("12.30.txt"); runQueries(ifs);
system("pause"); return 0; }
|