C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
2018-01-04 23:52
766 查看
// StrBlob类的定义.h文件#ifndef STRBLOB_H#define STRBLOB_H#include<vector>#include<string>#include<initializer_list>#include<memory>using namespace::std;class StrBlob{friend class QueryResultStrBlob;public:typedef vector<string>::size_type size_type;StrBlob();StrBlob(initializer_list<string>il);StrBlob(const StrBlob&); //拷贝构造size_type size() const { return data->size(); }bool empty() const { return data->empty(); }//添加和删除元素void push_back(const string& t) { data->push_back(t); }void pop_back();//元素访问string& front();string& back();const string& front() const;const string& back() const;const string& backi(size_type i) const;private:shared_ptr<vector<string>>data;void check(size_type i, const string& msg) const;};
//StrBlob类的实现.cpp文件 #include "StrBlob.h" StrBlob::StrBlob():data(make_shared<vector<string>>()) { } StrBlob::StrBlob(initializer_list<string>il) : data(make_shared<vector<string>>(il)) { } StrBlob::StrBlob(const StrBlob& strb) //拷贝构造,输入一定是常量类的引用 { data = strb.data; } void StrBlob::check(size_type i, const string& msg) const { if (i >= msg.size()) throw out_of_range(msg); } void StrBlob::pop_back() { check(0, "pop_back on empty StrBlob"); data->pop_back(); } string& StrBlob::front() { check(0,"front on empty StrBlob"); return data->front(); } string& StrBlob::back() { check(0,"back on empty StrBlob"); return data->back(); } const string& StrBlob::front() const { check(0, "front on empty StrBlob"); return data->front(); } const string& StrBlob::back() const //后面的const表示不能修改this指针,前面的const表示返回类型是const { check(0, "back on empty StrBlob"); return data->back(); } const string& StrBlob::backi(size_type i) const { check(0, "return element on empty StrBlob"); return *(data->begin() + i); }
// TextQueryStrBlob,QueryResultStrBlob类的定义.h文件 #ifndef TEXTQUERYSTRBLOB_H #define TEXTQUERYSTRBLOB_H #include<memory> #include<string> #include<vector> #include<map> #include<set> #include<fstream> #include<sstream> #include "StrBlob.h" class QueryResultStrBlob; class TextQueryStrBlob { public: using line_no = std::vector<std::string>::size_type; TextQueryStrBlob(std::ifstream&); QueryResultStrBlob query(const std::string&) const; private: StrBlob file; //输入文件,里面的智能指针指向一个空的vector<string> std::map<std::string, std::shared_ptr<std::set<line_no>>> wm;//每个单词到到它所在行号的集合的映射 }; class QueryResultStrBlob { friend std::ostream& print(std::ostream&, const QueryResultStrBlob&); public: using line_no = std::vector<std::string>::size_type; QueryResultStrBlob(std::string s, std::shared_ptr<std::set<line_no>> p,const StrBlob& f) : sought(s),lines(p),file(f) { } private: std::string sought; //查询单词 std::shared_ptr<std::set<line_no>> lines; //出现的行号 StrBlob file; //输入的文件 }; #endif;
// TextQueryStrBlob,QueryResultStrBlob类的实现.cpp文件#include "TextQueryStrBlob.h"using namespace::std;TextQueryStrBlob::TextQueryStrBlob(ifstream& infile){ string str;while (getline(infile, str)){file.push_back(str);int num = file.size() - 1; //当前行号istringstream istr(str);string word;while (istr >> word){auto &line = wm[word]; //line为行号的set的指针,如果word是第一次出现,则先添加word后绑定,否则直接line和指针绑定if (!line) //如果指向的是空对象,说明此word还没有创建新的set,要创建新的set,为后续插入行号做准备line.reset(new set<line_no>);//重新分配对象给lineline->insert(num); //如果一个单词在一行中出现多次,则只记录一次}}}QueryResultStrBlob TextQueryStrBlob::query(const string& word) const{//查询单词,把结果传给QueryResultauto ret = wm.find(word);if (ret != wm.end())return QueryResultStrBlob(word, ret->second,file);else{static shared_ptr<set<line_no>> p(new set<line_no>);return QueryResultStrBlob(word, p,file);}}string make_plural(size_t ctr, const string &word, const string &ending){return(ctr > 1) ? word + ending : word;}ostream &print(ostream& out, const QueryResultStrBlob& qr){out << qr.sought << " occurs " << qr.lines->size() << make_plural(qr.lines->size(), "times", "s") << endl;for (auto wq = qr.lines->begin(); wq != qr.lines->end(); ++wq){out << "(line " << *wq + 1 << ")" << qr.file.backi(*wq)<< endl;}return out;}
//测试文件.cpp#include<iostream>#include "TextQueryStrBlob.h"using namespace std;void RunQueriesStrBlob(ifstream &infile){TextQueryStrBlob 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 infile("wordtext.txt");RunQueriesStrBlob(infile);return 0;}输入文件:输出结果:
相关文章推荐
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用智能指针 用StrBlob代替vector<string> C++Primer 练习12.32
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27
- C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27