C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题](一)

2014-11-24 12:58:58 · 作者: · 浏览: 3

面向对象编程

--再谈文本查询示例[续/习题]


//P522 习题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
       
         eva l(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
        
          eva l(const TextQuery &t) const { return p -> eva l(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
         
           eva l(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
          
            eva l(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
           
             eva l(const TextQuery &) const; }; class OrQuery : public BinaryQuery { friend Query operator|(const Query &,const Query &); OrQuery(Query left,Query right): BinaryQuery(left,right,"|"){} set
            
              eva l(const TextQuery &) const; }; inline Query operator&(const Query &lhs,const Query &rhs) { return new AndQuery(lhs,rhs); } inline Query operator|(const Query &lhs,const Query &rhs) { return new OrQuery(lhs,rhs); } inline Query operator~(const Query &oper) { return new NotQuery(oper); } #endif // QUERY_H_INCLUDED 
            
           
          
         
        
       
      
     
    
   
  

//4 in Query.cpp
#include "Query.h"

set
  
   
OrQuery::eva l(const TextQuery &file) const
{
    set
   
     left = lhs.eva l(file), ret_lines = rhs.eva l(file); ret_lines.insert(left.begin(),left.e