C++ primer 文本查询程序 Query
来源:互联网 发布:造梦西游刷点卷软件 编辑:程序博客网 时间:2024/04/30 15:52
C++ primer 文本查询程序,面向对象的实现,有很多值得学习的知识点。
整理了代码如下,使用VS2010,g++编译通过:
#include <map>#include <set>#include <vector>#include <string>#include <algorithm>#include <iterator>#include <istream>#include <sstream> //istringstreamusing std::istringstream;using std::map;using std::set;using std::vector;using std::string;#include <iostream>using std::ostream;using std::cout;using std::cin;using std::cerr;using std::endl;#include <fstream>using std::getline;using std::ifstream;/** * @brief The TextQuery class */class TextQuery{public: typedef vector<string>::size_type line_no; void read_file(std::ifstream &is) { store_file(is); build_map(); } set<line_no> run_query(string &) const; string text_line(line_no) const; line_no size() const //the total lines num { return lines_of_text.size(); }private: void store_file(std::ifstream &); void build_map(); vector<string> lines_of_text; map<string,set<line_no> > word_map;};set<TextQuery::line_no> TextQuery::run_query(string &query_word) const{ map<string,set<line_no> >::const_iterator iter = word_map.find(query_word); if ( iter != word_map.end() ) { return iter->second; } return set<line_no>();}string TextQuery::text_line(line_no line) const{ return lines_of_text[line];}void TextQuery::store_file(std::ifstream &is){ string textline; while ( getline(is,textline) ) { lines_of_text.push_back(textline); }}void TextQuery::build_map(){ line_no line_num = 0; for ( ; line_num != lines_of_text.size() ; line_num++ ) { istringstream line(lines_of_text[line_num]); string word; while ( line>>word ) { word_map[word].insert(line_num); } }}/** * @brief The Query_base class */class Query_base{ friend class Query;protected: virtual ~Query_base() { }private: virtual set<TextQuery::line_no> eval(const TextQuery &) const = 0; virtual ostream & display(ostream &os = std::cout ) const = 0;};class Query{ friend Query operator~(const Query &); friend Query operator|(const Query &,const Query &); friend Query operator&(const Query &,const Query &);public: Query(const string &word); //builds a new wordQuery //copy control to manage pointers and counting Query(const Query &c):q(c.q),use(c.use) { ++*use; } ~Query() { decr_use(); } Query &operator=(const Query &query) { q = query.q; ++*use; return *this; } set<TextQuery::line_no> eval(const TextQuery &t) const { return q->eval(t); } std::ostream &display(std::ostream &os) const { return q->display(os); }private: Query(Query_base *query):q(query),use(new std::size_t(1)) { } Query_base *q; std::size_t *use; void decr_use() { if ( --*use == 0 ) { delete q; delete use; } }};inline ostream & operator<<(ostream &os,const Query &query) //why needed const for Query &??{ query.display(os); return os;}/** * @brief The WordQuery class */class WordQuery : public Query_base{ friend class Query; WordQuery(const string &s):query_word(s) { } set<TextQuery::line_no> eval(const TextQuery &t) const { return t.run_query((string &)query_word); //why needed const? } ostream & display(ostream &os = std::cout ) const; string query_word;};ostream & WordQuery::display(ostream &os) const{ return os<<query_word;}//Query constructor!! we can't define before the WordQuery class finishQuery::Query(const string &word) //builds a new wordQuery{ q = new WordQuery(word); use = new std::size_t(1);}/** * @brief The NotQuery class */class NotQuery :public Query_base{ friend Query operator~(const Query &); NotQuery(const Query &q):query(q) { } set<TextQuery::line_no> eval(const TextQuery &) const; //becareful the last const,if you forget to add it in the implement,it overloads and bug ostream & display(ostream &os) const; const Query query; //const is ok,when you initianize in the constructor};set<TextQuery::line_no> NotQuery::eval(const TextQuery &file) const{ set<TextQuery::line_no> has_val = query.eval(file); set<TextQuery::line_no> ret_lines; TextQuery::line_no n = 0; for ( ; n != file.size() ; ++n ) { if ( has_val.find(n) == has_val.end() ) { ret_lines.insert(n); } } return ret_lines;}ostream & NotQuery::display(ostream &os) const{ return os<<"~("<<query<<")";}/** * @brief The BinaryQuery class */class BinaryQuery : public Query_base{protected: //can't not be private BinaryQuery(Query left,Query right,string op):lhs(left),rhs(right),oper(op) { } ostream & display(ostream &os = std::cout ) const { return os<<"("<<lhs<<" "<<oper<<" "<<rhs<<")"; } Query lhs,rhs; string oper; //& |};/** * @brief The AndQuery class */class AndQuery : public BinaryQuery{ friend Query operator&(const Query &,const Query &); AndQuery(const Query &left,const Query &right):BinaryQuery(left,right,"&") { } set<TextQuery::line_no> eval(const TextQuery &) const;};set<TextQuery::line_no> AndQuery::eval(const TextQuery &file) const{ set<TextQuery::line_no> left = lhs.eval(file), right = rhs.eval(file); set<TextQuery::line_no> ret_lines; set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(ret_lines,ret_lines.begin())); return ret_lines;}/** * @brief The OrQuery class */class OrQuery : public BinaryQuery{ friend Query operator|(const Query &,const Query &); OrQuery(const Query lq,const Query rq):BinaryQuery(lq,rq,"|") { } set<TextQuery::line_no> eval(const TextQuery &) const;};set<TextQuery::line_no> OrQuery::eval(const TextQuery &file) const{ set<TextQuery::line_no> right = lhs.eval(file), ret_lines = rhs.eval(file); ret_lines.insert(right.begin(),right.end()); return ret_lines;}Query operator~(const Query &query){ return new NotQuery(query);}Query operator|(const Query &lhr,const Query &rhr){ return new OrQuery(lhr,rhr);}Query operator&(const Query &lhr,const Query &rhr){ return new AndQuery(lhr,rhr);}void print_result(const set<TextQuery::line_no> &locs,const TextQuery &file){ typedef set<TextQuery::line_no> line_nums; line_nums::const_iterator iter = locs.begin(); for( ; iter != locs.end() ; iter++ ) { cout<<"\tline"<<(*iter)+1<<")"<<file.text_line(*iter)<<endl; }}bool open_file(ifstream &is,char *filename){ if ( is.is_open() ) { is.close(); } is.open(filename); if ( is.is_open() == true ) { return true; } return false;}int main(){ ifstream infile; if ( !open_file(infile,(char *)"TextQuery.txt")) { cerr<<"No input file!"<<endl; return -1; } TextQuery tq; tq.read_file(infile); //Query q = Query("I") & Query("like") | Query("you"); //Query q = Query("you") & Query("like"); Query q = Query("I") & Query("like"); set<TextQuery::line_no> res = q.eval(tq); q.display(cout); cout<<endl; print_result(res,tq);}
测试文件为 TextQuery.txt ,内容如下,
I like you and hope you like me!
But you don't like me,I know that,I am so sad!
One day,will you like me?
0 0
- C++ primer 文本查询程序 Query
- 文本查询程序--摘自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习题10.6 文本查询程序
- C++ Primer 第五版 文本查询程序
- C++ primer 第十章 文本查询程序
- C++ Primer : 第十二章 : 文本查询程序
- 【C++ Primer】文本查询程序再探
- c++ primer CH15 文本布尔查询程序
- zend framework2中文教程汇总
- 乔布斯留给苹果的遗产
- Cocos2dx 3.0 过渡篇(一) 初体验
- 将传奇1.76移植到centos的尝试
- Mybatis中配置Mapper的方法
- C++ primer 文本查询程序 Query
- 【cocos2dx 3.3】口袋空战1 背景层
- JAVASCRIRP 如何退出整个框架
- 使用java/groovy扩展ant初步
- HDOJ1011 Starship Troopers
- sed
- BAE3.0定时任务设置
- HTML5 SVG用marker画箭头
- 无