Object-Oriented Programming -- let's talk about text query examples [Continue/exercise]
// P522 exercise 15.41 // 1 in TextQuery. h # ifndef TEXTQUERY_H_INCLUDED # define TEXTQUERY_H_INCLUDED # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
Using namespace std; class TextQuery {public: typedef std: vector
: Size_type line_no; typedef string: size_type str_size; void read_file (std: ifstream & is) {store_file (is); build_map ();} std: set
Run_query (const std: string &) const; std: string text_line (line_no) const; line_no size () const; private: void store_file (std: ifstream &); void build_map (); std: vector
Line_of_text; std: map <std: string, std: set
> Word_map;}; # endif // TEXTQUERY_H_INCLUDED
//2 in TextQuery.cpp#include "TextQuery.h"void TextQuery::store_file(ifstream &is){ string textline; while (getline(is,textline)) { line_of_text.push_back(textline); }}void TextQuery::build_map(){ for (line_no line_num = 0; line_num != line_of_text.size(); ++line_num) { istringstream line(line_of_text[line_num]); string word; while (line >> word) { word_map[word].insert(line_num); } }}set
TextQuery::run_query(const std::string &query_word) const{ map
>::const_iterator loc = word_map.find(query_word); if (loc == word_map.end()) { return set
(); } else { return loc -> second; }}string TextQuery::text_line(line_no line) const{ if (line < line_of_text.size()) { return line_of_text[line]; } throw out_of_range("line number out of range");}TextQuery::str_size TextQuery::size() const{ return line_of_text.size();}
//3 in Query.h#ifndef QUERY_H_INCLUDED#define QUERY_H_INCLUDED#include "TextQuery.h"#include
#include
#include
#include
#include using namespace std;class Query_base{ friend class Query;protected: typedef TextQuery::line_no line_no; virtual ~Query_base() {}private: virtual set
eval(const TextQuery &) const = 0; virtual ostream &display(ostream & = 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 &); Query(const Query &c):p(c.p),use(c.use) { ++ *use; } ~Query() { decr_use(); } Query &operator=(const Query &); set
eval(const TextQuery &t) const { return p -> eval(t); } ostream &display(ostream &os) const { return p -> display(os); }private: Query(Query_base *query): p(query),use(new std::size_t(1)) {} Query_base *p; std::size_t *use; void decr_use() { if ( -- *use == 0 ) { delete p; delete use; } }};inline Query &Query::operator=(const Query &rhs){ ++ * rhs.use; decr_use(); p = rhs.p; use = rhs.use; return *this;}inline ostream &operator<<(ostream &os,const Query &q){ return q.display(os);}class WordQuery : public Query_base{ friend class Query; WordQuery(const string &s):query_word(s) {} set
eval(const TextQuery &t) const { return t.run_query(query_word); } ostream &display(ostream &os) const { return os << query_word; } string query_word;};inline Query::Query(const string &s): p(new WordQuery(s)),use(new std::size_t(1)) {}class NotQuery : public Query_base{ friend Query operator~(const Query &); NotQuery(Query q):query(q) {} set
eval(const TextQuery &) const; ostream &display(ostream &os) const { return os << "~(" << query << ")"; } const Query query;};class BinaryQuery : public Query_base{protected: BinaryQuery(Query left,Query right,string op): lhs(left),rhs(right),oper(op) {} ostream &display(ostream &os) const { return os << "(" << lhs << " " << oper << " " << rhs << ")"; } const Query lhs,rhs; const string oper;};class AndQuery : public BinaryQuery{ friend Query operator&(const Query &,const Query &); AndQuery(Query left,Query right): BinaryQuery(left,right,"&"){} set
eval(const TextQuery &) const;};class OrQuery : public BinaryQuery{ friend Query operator|(const Query &,const Query &); OrQuery(Query left,Query right): BinaryQuery(left,right,"|"){} set
eval(const TextQuery &) const;};inline Queryoperator&(const Query &lhs,const Query &rhs){ return new AndQuery(lhs,rhs);}inline Queryoperator|(const Query &lhs,const Query &rhs){ return new OrQuery(lhs,rhs);}inline Queryoperator~(const Query &oper){ return new NotQuery(oper);}#endif // QUERY_H_INCLUDED
//4 in Query.cpp#include "Query.h"set
OrQuery::eval(const TextQuery &file) const{ set
left = lhs.eval(file), ret_lines = rhs.eval(file); ret_lines.insert(left.begin(),left.end()); return ret_lines;}set
AndQuery::eval(const TextQuery &file) const{ set
left = lhs.eval(file), right = rhs.eval(file); set
ret_lines; set_intersection(left.begin(),left.end(), right.begin(),right.end(), inserter(ret_lines,ret_lines.begin())); return ret_lines;}set
NotQuery::eval(const TextQuery &file) const{ set
hav_val = query.eval(file); set
ret_val; for (line_no n = 0; n != file.size(); ++n) { if (hav_val.find(n) == hav_val.end()) { ret_val.insert(n); } } return ret_val;}
// 5 in main. cpp // test data is the same as above # include
# Include "TextQuery. h "# include" Query. h "using namespace std; int main () {ifstream inFile (" input "); TextQuery file; file. read_file (inFile); Query q = Query ("fiery") & Query ("bird") | Query ("wind"); cout <"Executed Query: "<q <endl; typedef set
Line_nums; const line_nums & locs = q. eval (file); cout <"match occurs" <locs. size () <"times" <endl; line_nums: const_iterator it = locs. begin (); for (; it! = Locs. end (); ++ it) {cout <"\ t (line" <(* it) + 1 <")" <file. text_line (* it) <endl ;}}
Running example: