支持逻辑运算符的文本查询程序的OOP实现

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
         #include 
         
           #include 
          
            #include 
           
             using namespace std; //All of classes are pointer class QueryResult { friend ostream& print (ostream&, const QueryResult&); public: using line_no = vector 
            
              ::size_type; set 
             
               ::iterator begin() const { return lines->begin (); } set 
              
                ::iterator end() const { return lines->end (); } shared_ptr 
                
                
                  > get_file()const { return file; } QueryResult (string s, shared_ptr 
                  
                  
                    > p, shared_ptr 
                    
                    
                      > f) :sought (s), lines (p), file (f) {} private: string sought; //we want share the data in the file & line_no //so we defind these as smart pointer shared_ptr 
                      
                      
                        > file; shared_ptr 
                        
                        
                          > lines; }; ostream& print (ostream& os, const QueryResult& query) { os << query.sought << " occurs " << query.lines->size () << " " << ((query.lines->size () > 1) ? "times" : "time") << endl; for (auto num : *query.lines) os << "\t(line" << num + 1 << ")" << *(query.file->begin () + num) << endl; return os; } class TextQuery { public: using line_no = vector 
                         
                           ::size_type; //store the input file TextQuery (ifstream&); QueryResult query (const string&)const; private: shared_ptr 
                           
                           
                             >file; //each word corresponds to a collection store it's line_no map 
                            
                              >>word_map; }; TextQuery::TextQuery (ifstream& is) :file (new vector 
                             
                               ) { string text; while (getline (is, text)) { file->push_back (text); //current line_no int n = file->size () - 1; istringstream line (text); string word; while (line >> word) { //lines is shared_ptr 
                              
                                auto &lines = word_map[word]; //create a new set store the line_no of the new word if (!lines) lines.reset (new set 
                               
                                 ); //store the line_no lines->insert (n); } } } QueryResult TextQuery::query (const string& s)const { //if not exist, return empty shared_ptr static shared_ptr 
                                 
                                 
                                   >nodata (new set 
                                  
                                    ); auto loc = word_map.find (s); return ((loc == word_map.end ()) ? QueryResult (s, nodata, file) : QueryResult (s, loc->second, file)); } //the root of the query system adapt other class class Query_base { friend class Query; protected: using line_no = TextQuery::line_no; virtual ~Query_base () = default; private: //eval return the QueryResult corresponded to current Query virtual QueryResult eval (const TextQuery&)const = 0; //rep turn the query to string virtual string rep ()const = 0; }; //the interface to hide the query system 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&); QueryResult eval (const TextQuery &tq) const { return q->eval (tq); } string rep ()const { return q->rep (); } private: //clare as private means to prevent user defind a new Query_base casually Query (shared_ptr 
                                   
                                     query):q(query) {} shared_ptr 
                                    
                                      q; }; ostream &operator<<(ostream os, const Query &query) { return os << query.rep(); } //query a word class WordQuery:public Query_base { friend class Query; WordQuery (const string &s) :query_word (s) {} QueryResult eval (const TextQuery &tq)const override { return tq.query (query_word);} string rep ()const override { return query_word; } string query_word; }; inline Query::Query (const string &s):q (new WordQuery(s)){}; //accept a Query, execute the operator~ class NotQuery :public Query_base { friend Query operator~(const Query &); NotQuery (const Query &q) :query (q) {} string rep ()const override { return "~(" + query.rep () + ")"; } QueryResult eval (const TextQuery &tq)const override; Query query; }; inline Query operator~(const Query &q) { return shared_ptr 
                                     
                                       (new NotQuery (q)); } //BinaryQuery is also an virtual class class BinaryQuery:public Query_base { protected: BinaryQuery (const Query &l, const Query &r, const string &s) :lhs (l), rhs (r), opSym (s) {} string rep ()const override { return "(" + lhs.rep () + " " + opSym + " " + rhs.rep () + ")"; } Query lhs, rhs; //name of the operator string opSym; }; class AndQuery :public BinaryQuery { friend Query operator&(const Query &, const Query &); AndQuery (const Query &left, const Query &right) :BinaryQuery (left, right, "&") {} QueryResult eval (const TextQuery &)const override; }; inline Query operator&(const Query &lhs, const Query &rhs) { return shared_ptr 
                                      
                                        (new AndQuery (lhs, rhs)); } class OrQuery :public BinaryQuery { friend Query operator|(const Query &, const Query &); OrQuery (const Query &left, const Query &right) :BinaryQuery (left, right, "|") {} QueryResult eval (const TextQuery &)const override; }; inline Query operator|(const Query &lhs, const Query &rhs) { return shared_ptr 
                                       
                                         (new OrQuery (lhs, rhs)); } //return the union of the rhs & lhs'query result QueryResult OrQuery::eval (const TextQuery &text)const { auto right = rhs.eval (text), left = lhs.eval (text); //insert the left auto ret_lines = make_shared 
                                         
                                         
                                           > (left.begin (), left.end ()); //insert the right ret_lines->insert (right.begin (), right.end ()); //left & right point to the same file return QueryResult (rep (), ret_lines, left.get_file ()); } //return the intersection of the rhs & lhs's query result QueryResult AndQuery::eval (const TextQuery &text)const { auto right = rhs.eval (text), left = lhs.eval (text); auto ret_lines = make_shared 
                                           
                                           
                                             > (); //STL set_intersection(first_range, second_range, dest_place) set_intersection (right.begin (), right.end (), left.begin (), left.end (), inserter (*ret_lines, ret_lines->begin ())); return QueryResult (rep (), ret_lines, left.get_file ()); } QueryResult NotQuery::eval (const TextQuery &text)const { auto result = query.eval (text); auto ret_lines = make_shared 
                                             
                                             
                                               > (); auto begin = result.begin (), end = result.end (); auto sz = result.get_file ()->size (); for (size_t n = 0; n < sz; ++n) { //before we process all of the lines in result //we must check if current line exist if (begin == end || *begin != n) ret_lines->insert (n); //what we need is the word not in the query result else ++begin; } return QueryResult (rep (), ret_lines, result.get_file ()); } void RunTextQueryTest (ifstream &infile) { TextQuery tq (infile); while (true) { cout << "enter something or press Ctrl+Z to exit\n"; cout << "Excuting Query for: "; string input; if (!(cin >> input))break; print (cout, tq.query(input)); } } int main (int argc, char *argv[]) { std::ios::sync_with_stdio (false); ifstream in; in.open (argv[1]); TextQuery tq (in); auto q = Query("Your") & Query("is") | Query("of"); print (cout, q.eval (tq)); return 0; } 
                                              
                                             
                                            
                                           
                                          
                                         
                                        
                                       
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
       
      
      
     
     
    
    
   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值