文本查詢程序——標準庫學習小結
阿新 • • 發佈:2017-11-17
出現的次數 mes ati clu insert res static stat 文件
程序:允許用戶在一個給定文件中查詢單詞,查詢結果是單詞在文件中出現的次數及其所在行的列表。如果一個單詞在一行中出現多次,此行只列出一次。
#include <iostream> #include <fstream> #include <sstream> #include <memory> #include <map> #include <set> #include <vector> #include <string> using namespace std; class QueryResult; //保存輸入文件 class TextQuery { using lineNo = vector<string>::size_type; public: TextQuery(ifstream &is); QueryResult query(const string&) const; private: shared_ptr<vector<string>> file; map<string, shared_ptr<set<lineNo>>> imap; }; //保存查詢結果 class QueryResult { using lineNo = vector<string>::size_type; friend ostream& operator<<(ostream&, const QueryResult&); public: QueryResult(const string &s, shared_ptr<vector<string>> f, shared_ptr<set<lineNo>> l) :sword(s), file(f), line(l) {} private: string sword; shared_ptr<vector<string>> file; shared_ptr<set<lineNo>> line; }; TextQuery::TextQuery(ifstream &is) :file(make_shared<vector<string>>()) { string line; while (getline(is, line)) { file->push_back(line); istringstream in(line); auto l = file->size() - 1; string word; while (in >> word) { shared_ptr<set<lineNo>> &r = imap[word]; if (!r) r.reset(new set<lineNo>); r->insert(l); } } } QueryResult TextQuery::query(const string &word) const { static shared_ptr<set<lineNo>> nodata(new set<lineNo>); auto it = imap.find(word); if (it != imap.end()) return QueryResult(word, file, it->second); else return QueryResult(word, file, nodata); } ostream& operator<<(ostream &os, const QueryResult &qr) { auto cnt = qr.line->size(); os << qr.sword << " occurs " << cnt << (cnt > 1 ? " times" : " time") << endl; for (auto l : *qr.line) { os << "\t(line " << l + 1 << ") " << *(qr.file->begin() + l) << endl; } return os; } int main() { ifstream in("data.txt"); TextQuery tq(in); cout << "請輸入要查詢的單詞:\n"; string s; while (cin >> s) { cout << tq.query(s) << endl; cout << "請輸入要查詢的單詞:\n"; } return 0; }
文本查詢程序——標準庫學習小結