c++primer里的文本查询程序扩展
来源:互联网 发布:深圳少儿编程培训 编辑:程序博客网 时间:2024/05/17 08:43
感觉这个例子很锻炼面向对象思想,所以还是写下来吧
Query_base.h
#pragma once# include"TextQuery.h"# include"QueryResult.h"# include<string>//这是一个抽象基类,具体的查询类型从中派生,所有成员都是private的class Query_base{ friend class Query;protected: using line_no = TextQuery::line_no; //用于eval函数 virtual ~Query_base() = default;private: //eval返回与当前Query匹配的QueryResult virtual QueryResult eval(const TextQuery &)const = 0; virtual std::string rep()const = 0;};
Query.h
#pragma once# include<string># include"QueryResult.h"# include"TextQuery.h"# include"Query_base.h"# include<iostream>//这是一个管理Query_base继承体系的的接口类class Query{ //这些运算符需要访问接受shared_ptr的构造函数,而该函数是私有的 friend Query operator~(const Query&); friend Query operator|(const Query&,const Query&); friend Query operator&(const Query&, const Query&);public: Query(const std::string&);//构建一个新的WordQuery //接口函数:调用对应的Query_base操作 QueryResult eval(const TextQuery&t)const; std::string rep()const;private: Query(std::shared_ptr<Query_base> query); std::shared_ptr<Query_base> q;};
Query.cpp
# include"Query.h"# include"WordQuery.h"# include<string># include<iostream>QueryResult Query::eval(const TextQuery&t)const{ return q->eval(t);}std::string Query::rep()const{ return q->rep();}Query::Query(const std::string&s):q(new WordQuery(s)){}std::ostream&operator<<(std::ostream&os, const Query&query){ //Query::rep通过它的Query_base指针对rep()进行了虚调用 return os << query.rep();}Query::Query(std::shared_ptr<Query_base> query) :q(query) {}
TextQuery.h
# pragma once# include"QueryResult.h"# include<vector># include<fstream># include<memory># include<map># include<set>class QueryResult;//为了定义函数query的返回类型,这个定义是必须的class TextQuery{public: using line_no = std::vector<std::string>::size_type; TextQuery(std::ifstream &); QueryResult query(const std::string &)const;private: std::shared_ptr<std::vector<std::string>> file; //输入文件 std::map<std::string, std::shared_ptr<std::set<line_no>>> wm;};
TextQuery.cpp
# include"TextQuery.h"# include<vector># include<string># include<sstream># include"QueryResult.h"class QueryResult;using namespace std;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) //对行中每个单词 { //如果单词不在wm中,以之为下标在wm中添加一项 auto &lines = wm[word];//lines是一个sharred_ptr if (!lines) //在我们第一次遇到这个单词时,此指针为空 lines.reset(new set < line_no>);//分配一个新的set lines->insert(n); //将此行号插入set中 } }}QueryResult TextQuery::query(const string &sought)const{ //如果未找到sought,我们将返回一个指向此set的指针 static shared_ptr<set<line_no>> nodata(new set<line_no>); //使用find而不是下标运算符来查找单词,避免将单词添加到wm中 auto loc = wm.find(sought); if (loc == wm.end()) return QueryResult(sought, nodata, file); //未找到 else return QueryResult(sought, loc->second, file);}
QueryResult.h
# pragma once# include<iostream># include"TextQuery.h"# include<memory># include<set># include<vector># include<string>class QueryResult{ friend std::ostream& print(std:: ostream &, const QueryResult&);public: using size = std::vector<std::string>::size_type; QueryResult(std::string s, std::shared_ptr<std::set<size>> p, std::shared_ptr<std::vector<std::string>> f); std::set<size>::iterator begin(); std::set<size>::iterator end(); std::shared_ptr<std::vector<std::string>> get_file();private: std::string sought;//查询单词 std::shared_ptr<std::set<size>> lines;//出现的行号 std::shared_ptr<std::vector<std::string>> file; //输入文件};
QueryResult.cpp
# include"QueryResult.h"# include"TextQuery.h"using size = std::vector<std::string>::size_type;QueryResult::QueryResult(std::string s, std::shared_ptr<std::set<size>> p, std::shared_ptr<std::vector<std::string>> f):sought(s), lines(p), file(f) {}std::set<size>::iterator QueryResult::begin(){ return this->lines->begin();}std::set<size>::iterator QueryResult::end(){ return this->lines->end();}std::shared_ptr<std::vector<std::string>> QueryResult::get_file(){ return this->file;}
WordQuery.h
#pragma once# include"Query_base.h"# include<string>class WordQuery:public Query_base{ friend class Query; //Query使用WordQuery构造函数 WordQuery(const std::string &s); //具体的类:WordQuery将定义所有继承+而来的纯虚函数 QueryResult eval(const TextQuery&t)const; std::string rep()const; std::string query_word; //要查找的单词};
WordQuety.cpp
# include"WordQuery.h"WordQuery::WordQuery(const std::string &s) :query_word(s) {}//具体的类:WordQuery将定义所有继承而来的纯虚函数QueryResult WordQuery::eval(const TextQuery&t)const{ return t.query(query_word);}std::string WordQuery::rep()const{ return query_word;}
BinaryQuery.h
# pragma once# include"Query.h"# include"Query_base.h"class BinaryQuery:public Query_base{protected: BinaryQuery(const Query &l, const Query &r, std::string s); //抽象类:BinaryQuery不定义eval std::string rep()const; Query lhs,rhs; //右侧和左侧运算对象 std::string opSym; //运算符的名字};
BinaryQuery.cpp
# include"BinaryQuery.h"BinaryQuery::BinaryQuery(const Query &l, const Query &r, std::string s) : lhs(l), rhs(r), opSym(s) {}std::string BinaryQuery::rep()const{ return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")";}
AndQuery.h
#pragma once# include"BinaryQuery.h"class AndQuery:public BinaryQuery{ friend Query operator&(const Query&, const Query&); AndQuery(const Query&left, const Query&right); //具体的类:AndQuery继承了rep并且定义了其他纯虚函数 QueryResult eval(const TextQuery&)const;};
AndQuery.cpp
# include"AndQuery.h"# include<set># include<memory># include<algorithm># include<iterator>AndQuery::AndQuery(const Query&left, const Query&right) : BinaryQuery(left, right, "&") {}Query operator&(const Query&lhs, const Query &rhs){ return std::shared_ptr<Query_base>(new AndQuery(lhs, rhs));}QueryResult AndQuery::eval(const TextQuery&text)const{ //通过Query运算对象进行的虚调用,以获得运算对象的查询结果set auto left = lhs.eval(text), right = rhs.eval(text); //保存left和right的交集的set auto ret_lines = std::make_shared<std::set<line_no>>(); //将两个范围的交集写入一个目的迭代器中 //本次调用的目的迭代器向ret添加元素 std::set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin())); return QueryResult(rep(), ret_lines, left.get_file());}
OrQuery.h
#pragma once# include"BinaryQuery.h"class OrQuery :public BinaryQuery{ friend Query operator|(const Query&, const Query&); OrQuery(const Query&left, const Query&right); //具体的类:AndQuery继承了rep并且定义了其他纯虚函数 QueryResult eval(const TextQuery&)const;};
OrQuery.cpp
# include"OrQuery.h"# include<memory># include<set># include"BinaryQuery.h"# include"Query_base.h"# include"Query.h"OrQuery::OrQuery(const Query&left, const Query&right) : BinaryQuery(left, right, "|") {}QueryResult OrQuery::eval(const TextQuery&text)const{ //通过Query成员lhs和rhs进行的虚调用 //调用eval返回每个运算对象的QueryResult auto right = rhs.eval(text), left = lhs.eval(text); //将左侧运算对象的行号拷贝到结果Set中 auto ret_lines = std::make_shared<std::set<line_no>>(left.begin(), left.end()); //插入右侧运算对象所得的行号 ret_lines->insert(right.begin(), right.end()); //返回一个新的QueryResult,它表示lhs和rhs的并集 return QueryResult(rep(), ret_lines, left.get_file());} Query operator|(const Query&lhs, const Query &rhs){ return std::shared_ptr<Query_base>(new OrQuery(lhs, rhs));}
NotQuery.h
#pragma once# include"Query_base.h"# include"Query.h"class NotQuery:public Query_base{ friend Query operator~(const Query&); NotQuery(const Query&q); //具体的类:NotQuery将定义所有继承而来的纯虚函数 std::string rep()const; QueryResult eval(const TextQuery&) const; Query query;};
NotQuery.cpp
# include"NotQuery.h"# include<memory># include<set># include"QueryResult.h"class QueryResult;NotQuery::NotQuery(const Query&q) :query(q) {}std::string NotQuery::rep()const{ return "~(" + query.rep() + ")";}QueryResultNotQuery::eval(const TextQuery&text)const{ auto result = query.eval(text); auto ret_lines=std::make_shared<std::set<line_no>>(); auto beg = result.begin(), end = result.end(); auto sz = result.get_file()->size(); for (size_t n = 0;n != sz;++n) { if (beg == end || *beg != n) ret_lines->insert(n); else if (beg != end)++beg; } return QueryResult(rep(), ret_lines, result.get_file());}Query operator~(const Query&operand){ //return std::shared_ptr<Query_base>(new NotQuery(operand)); //等价于: std::shared_ptr<Query_base> tmp(new NotQuery(operand)); return Query(tmp);}
先来查找单个单词,main.cpp
# include<iostream># include<fstream># include<string># include"Query.h"# include"QueryResult.h"# include"TextQuery.h"# include"WordQuery.h"using namespace std;std::ostream& print(std::ostream &, const QueryResult&);std::string make_plural(size_t i, const std::string &word, const std::string &end){ return i == 1 ? word : word + end;}int main(){ std::ifstream fin("E:\\项目\\c++\\文本查询程序2\\文本查询程序2\\file.txt"); TextQuery text(fin); Query a1("windows"); Query a2("class"); Query b1=~a1; Query b2 = a1&a1; Query b3 = a1 | a1; auto s = a1.rep(); cout << s << endl; const auto result = a1.eval(text); print(std::cout, result); fin.close(); system("pause"); return 0;}std::ostream& print(std::ostream &os, const QueryResult&qr){ os << qr.sought << " occus " << qr.lines->size() << " "\ << make_plural(qr.lines->size(), "time", "s") << std::endl; for (auto num : *qr.lines) os << "\t(line " << num + 1 << ")\t" << *(qr.file->begin() + num) << std::endl; return os;}
查找单词windows:
接下来查找没有单词a1的:
查找同时出现a1和a2:
查找出现a1或a2:
0 0
- c++primer里的文本查询程序扩展
- 文本查询程序--摘自c++primer
- 【足迹C++primer】41、文本查询程序
- 【足迹C++primer】56、文本查询程序
- C++Primer 【笔记】文本查询程序 TextQuery
- C++primer学习:文本查询程序
- c++primer 实现文本统计的程序
- C++ primer 文本查询程序
- <<c++ primer>>文本查询程序
- C++primer 文本查询练习
- c++primer 文本查询 源代码
- c++primer文本查询系统
- 一个简单的文本查询程序—摘至《C++ Primer》
- c++ primer--容器的综合应用:文本查询程序
- c++ primer习题10.6 文本查询程序
- C++ Primer 第五版 文本查询程序
- C++ primer 第十章 文本查询程序
- C++ primer 文本查询程序 Query
- Android handler常见api
- 烧程序测试记录Day1
- 动态规划
- linux1
- params可变参数
- c++primer里的文本查询程序扩展
- InputStream与OutputStream文件操作
- hdu2669 Romantic(扩展欧几里得入门)
- 人工智能会不会取代开发它的人?
- 日期问题模版ZOJ Problem Set -3950 How Many NinesZOJ 找9
- COGS 729. [网络流24题] 圆桌聚餐
- Fragment实战案例
- 关于多条数据中,在多条开始时间结束时间中取最大交集
- 使用Apache的ab工具进行网站性能测试