zoukankan      html  css  js  c++  java
  • C++ 文本查询2.0(逻辑查询)

    代码实例实现了继承和友元之间的关系,以及为了隐藏实际继承实现,而实现的接口类,代码偏乱,楼主- -自看的(提醒作用)

    TextQuery.h

     1 //
     2 // Created by 徐爱东 on 17/7/19.
     3 //
     4 
     5 #ifndef TEXTQUERY_2_0_TEXTQUERY_H
     6 #define TEXTQUERY_2_0_TEXTQUERY_H
     7 
     8 #include <iostream>
     9 #include <map>
    10 #include <set>
    11 #include <vector>
    12 #include <string>
    13 #include <memory>
    14 #include <sstream>
    15 #include <fstream>
    16 
    17 
    18 class QueryResult
    19 {
    20     friend std::ostream &operator<<(std::ostream &os, const QueryResult &result);
    21 
    22     typedef std::vector<std::string>::size_type line_no;
    23 public:
    24     QueryResult(const std::string &word, std::shared_ptr<std::set<line_no> > lines,
    25                 std::shared_ptr<std::vector<std::string>> files);
    26 
    27     std::set<line_no>::iterator begin()
    28     {
    29         return lines_->begin();
    30     }
    31 
    32     std::set<line_no>::iterator end()
    33     {
    34         return lines_->end();
    35     }
    36 
    37     std::shared_ptr<std::vector<std::string> > get_file()
    38     {
    39         return files_;
    40     }
    41 
    42 private:
    43     std::string word_;    //查询单词
    44     std::shared_ptr<std::set<line_no>> lines_;    //单词出现行数集合
    45     std::shared_ptr<std::vector<std::string>> files_;          //根据的文件
    46 
    47 };
    48 
    49 
    50 class TextQuery
    51 {
    52 public:
    53     // using line_no=std::vector<std::string>::size_type ;
    54     typedef std::vector<std::string>::size_type line_no;    //C++11
    55 
    56 
    57     TextQuery(std::fstream &in);
    58 
    59     QueryResult query(const std::string &word) const;
    60 
    61 private:
    62     std::shared_ptr<std::vector<std::string> > filecontext_;      //文件内容
    63     std::map<std::string, std::shared_ptr<std::set<line_no> > > wordlinesset_;      //单词集合
    64 };
    65 
    66 
    67 #endif //TEXTQUERY_2_0_TEXTQUERY_H

    TextQuery.cpp

     1 //
     2 // Created by 徐爱东 on 17/7/19.
     3 //
     4 
     5 #include "TextQuery.h"
     6 
     7 QueryResult::QueryResult(const std::string &word, std::shared_ptr<std::set<line_no> > lines,
     8                          std::shared_ptr<std::vector<std::string>> files)
     9         : word_(word), lines_(lines), files_(files)
    10 {
    11 
    12 }
    13 
    14 
    15 std::ostream &operator<<(std::ostream &os, const QueryResult &result)
    16 {
    17     if (!result.lines_)
    18     {
    19         return os << result.word_ << " apprear 0 time:
    ";
    20 
    21     } else
    22     {
    23         os <<"
    "<< result.word_ << " appear " << result.lines_->size()
    24            << (result.lines_->size() > 1 ? " times:" : " time:") << "
    
    ";
    25 
    26 
    27         for (auto iter = result.lines_->cbegin();
    28              iter != result.lines_->cend(); iter = (result.lines_->upper_bound(*iter)))
    29         {
    30             os << "					(line" << *iter + 1 << "): " << *(result.files_->begin() + *iter) << std::endl<<std::endl;
    31         }
    32 
    33         return os;
    34     }
    35 }
    36 
    37 
    38 TextQuery::TextQuery(std::fstream &in)
    39         : filecontext_(new std::vector<std::string>{})
    40 {
    41     std::string line;
    42     std::stringstream stream;
    43 
    44     //每次获得一行
    45     while (std::getline(in, line))
    46     {
    47         stream.clear();
    48         filecontext_->push_back(line);
    49         auto linenumber = filecontext_->size() - 1;
    50 
    51 
    52         stream << line;
    53         while (stream >> line)
    54         {
    55             //没有则创建,有则返回只能指针;
    56             auto& lineset = wordlinesset_[line];
    57 
    58             if (!lineset)
    59                 lineset.reset(new std::set<line_no>);
    60 
    61             //记录行号
    62             lineset->insert(linenumber);
    63         }
    64 
    65     }
    66 
    67 
    68 }
    69 
    70 QueryResult TextQuery::query(const std::string &word) const
    71 {
    72     if (wordlinesset_.find(word) == wordlinesset_.end())
    73     {
    74         std::shared_ptr<std::set<line_no> > null_sharedptr(new std::set<line_no>);
    75         return QueryResult(word, null_sharedptr, filecontext_);
    76 
    77     } else
    78     {
    79         return QueryResult(word, wordlinesset_.find(word)->second, filecontext_);
    80     }
    81 
    82 }

    Query.h & QueryBase{WordQuery,NotQuery,BinaryQuery{AndQuery,OrQUery}};

    基本关系:Query是接口类,QueryBase是抽象类,WordQUery,NotQuery实现类,BinaryQuery抽象类(重构),AndQuery,OrQUery实际类

      1 //
      2 // Created by 徐爱东 on 17/7/19.
      3 //
      4 
      5 #ifndef TEXTQUERY_2_0_QUERY_BASE_H
      6 #define TEXTQUERY_2_0_QUERY_BASE_H
      7 
      8 #include "TextQuery.h"
      9 
     10 class Query;
     11 
     12 class WordQuery;
     13 
     14 class NotQuery;
     15 
     16 class AndQuery;
     17 
     18 class OrQuery;
     19 
     20 //抽象类
     21 class Query_base
     22 {
     23     //接口类,用于隐藏继承结构
     24     friend class Query;;
     25 private:
     26     virtual QueryResult eval(const TextQuery &) const =0;
     27 
     28     virtual std::string rep() const =0;
     29 
     30 protected:
     31     using line_no=TextQuery::line_no;
     32 
     33     virtual ~Query_base() = default;
     34 
     35 };
     36 
     37 
     38 class Query
     39 {
     40     friend class Query_base;
     41 
     42     friend class WordQuery;
     43 
     44     friend class NotQuery;
     45 
     46     friend class AndQuery;
     47 
     48     friend class OrQuery;
     49 
     50 
     51     //运算符操作需要访问私有shared_ptr,所以声明为友元
     52     friend Query operator~(const Query &);
     53 
     54     friend Query operator&(const Query &lhs, const Query &rhs);
     55 
     56     friend Query operator|(const Query &l, const Query &r);
     57 
     58 
     59     friend std::ostream &operator<<(std::ostream &os, const Query query)
     60     {
     61         return os << query.rep();
     62     }
     63 
     64 
     65 public:
     66     Query(const std::string &word);    //普通单单词查询,WordQuery;
     67 
     68     //接口函数,因为不是继承Query_base
     69     QueryResult eval(const TextQuery &text) const
     70     {
     71         return q->eval(text);
     72     }
     73 
     74     std::string rep() const
     75     {
     76         return q->rep();
     77     }
     78 
     79 private:
     80     //shared_ptr构造,为了使用动态虚调用
     81     //private 不允许外部调用
     82     Query(std::shared_ptr<Query_base> query) : q(query)
     83     {};
     84     std::shared_ptr<Query_base> q;
     85 };
     86 
     87 
     88 //唯一实际查询的类
     89 class WordQuery : public Query_base
     90 {
     91     //所有成员皆为private
     92     friend class Query;     //Query 需要使用构造函数
     93 
     94     std::string word_;
     95 
     96     WordQuery(const std::string &word) : word_(word)
     97     {}
     98 
     99 
    100     QueryResult eval(const TextQuery &Tq) const override
    101     {
    102         return Tq.query(word_);
    103     }
    104 
    105     std::string rep() const override
    106     {
    107         return word_;
    108     }
    109 
    110 };
    111 
    112 
    113 //取反的Query
    114 class NotQuery : public Query_base
    115 {
    116 
    117     friend Query operator~(const Query &);
    118 
    119     NotQuery(const Query &q) : query_(q)
    120     {
    121 
    122     }
    123 
    124     Query query_;
    125 
    126     //"~单词"返回的结果
    127     QueryResult eval(const TextQuery &Tq) const override
    128     {
    129         auto result = query_.eval(Tq);
    130 
    131         auto ret_line = std::make_shared<std::set<std::vector<std::string>::size_type>>();
    132         auto set = std::make_shared<std::set<std::vector<std::string>::size_type> >(result.begin(), result.end());
    133 
    134         auto file_line = result.get_file()->size();
    135 
    136         for (auto line = 0; line != file_line; line++)
    137         {
    138             //不在set里
    139             if (set->find(line + 1) == set->end())
    140             {
    141                 //添加
    142                 ret_line->insert(line);
    143             }
    144         }
    145 
    146         return QueryResult(query_.rep(), ret_line, result.get_file());
    147 
    148     }
    149 
    150     std::string rep() const override
    151     {
    152         return "~(" + query_.rep() + ")";//表示不需要查询的单词
    153     }
    154 };
    155 
    156 
    157 
    158 
    159 //BinaryQuery类,一个抽象基类,因为继承了基类的纯虚函数eval()
    160 //重构
    161 class BinaryQuery : public Query_base
    162 {
    163     friend class Query;;
    164 protected:
    165     BinaryQuery(const Query &l, const Query &r, const std::string &operaname)
    166             : lhs_(l),
    167               rhs_(r),
    168               operaname_(operaname)
    169     {
    170 
    171     }
    172 
    173     Query lhs_, rhs_;
    174     std::string operaname_;
    175 
    176 //    QueryResult eval(const TextQuery &) const
    177 //    {
    178 //
    179 //    }
    180 
    181     std::string rep() const
    182     {
    183         return "(" + lhs_.rep() + " " + operaname_ + " " + rhs_.rep() + ")";
    184     }
    185 };
    186 
    187 class AndQuery : public BinaryQuery
    188 {
    189     friend class Query;;
    190 protected:
    191     friend Query operator&(const Query &, const Query &);
    192 
    193     AndQuery(const Query &l, const Query &r) : BinaryQuery(l, r, "&")
    194     {}
    195 
    196     QueryResult eval(const TextQuery &text) const
    197     {
    198         //通过Query成员进行虚调用
    199         //调用eval返回每个QueryResult结果
    200         auto right = lhs_.eval(text), left = rhs_.eval(text);
    201         //空的目标容器
    202         auto ret_lines = std::make_shared<std::set<std::vector<std::string>::size_type>>();
    203 
    204         //取交集放入re_lines;
    205         std::set_intersection(right.begin(), right.end(),
    206                               left.begin(), left.end(),
    207                               std::inserter(*ret_lines, ret_lines->begin()));
    208 
    209         return QueryResult(rep(), ret_lines, right.get_file());
    210     }
    211 
    212 };
    213 
    214 
    215 
    216 class OrQuery : public BinaryQuery
    217 {
    218     friend class Query;;
    219 protected:
    220     friend Query operator|(const Query &, const Query &);
    221 
    222     OrQuery(const Query &l, const Query &r) : BinaryQuery(l, r, "|")
    223     {}
    224 
    225     QueryResult eval(const TextQuery &text) const
    226     {
    227         //通过Query成员lhs和rhs进行虚调用
    228         //调用eval返回每个运算对象的QueryResult
    229         auto right = lhs_.eval(text), left = rhs_.eval(text);
    230         auto ret_lines = std::make_shared<std::set<std::vector<std::string>::size_type> >(right.begin(), right.end());
    231         //进行并集操作y
    232         ret_lines->insert(left.begin(), left.end());
    233         return QueryResult(rep(), ret_lines, right.get_file());
    234     }
    235 };
    236 
    237 //每个Query都先生成基本WordQuery基础
    238 inline Query::Query(const std::string &word) : q(new WordQuery(word))
    239 { std::cout << "Query" << std::endl; }
    240 
    241 
    242 
    243 inline Query operator~(const Query &q)
    244 {
    245     return std::shared_ptr<Query_base>(new NotQuery(q));
    246 }
    247 
    248 inline Query operator&(const Query &lhs, const Query &rhs)
    249 {
    250     return std::shared_ptr<Query_base>(new AndQuery(lhs, rhs));
    251 }
    252 
    253 inline Query operator|(const Query &l, const Query &r)
    254 {
    255     return std::shared_ptr<Query_base>(new OrQuery(l, r));
    256 }
    257 
    258 
    259 #endif //TEXTQUERY_2_0_QUERY_BASE_H

    main.cpp

     1 #include <iostream>
     2 #include "Query_base.h"
     3 
     4 
     5 int main()
     6 {
     7     std::fstream file_("Text.txt", std::ios::in);
     8     std::vector<std::string> str_vec;
     9     std::vector<Query> que_vec;
    10 
    11     if (file_.is_open())
    12     {
    13         TextQuery file(file_);
    14 
    15         std::string word1, word2;
    16         do
    17         {
    18             std::cout << "Input word you want('quit to exit'): ";
    19             std::cin >> word1 >> word2;
    20 
    21             if (word1 == "quit")
    22             {
    23                 break;
    24             }
    25 
    26 
    27             Query query1(word1), query2(word2);
    28             auto q = query1 & query2;
    29             std::cout << q.rep() << std::endl;
    30             std::cout << q.eval(file) << std::endl;
    31             word1.clear();
    32         } while (1);
    33 
    34     }
    35 
    36     file_.close();
    37 
    38     return 0;
    39 }

    缺点:本来想实现字符串读取分隔实现动态逻辑Query联合,太麻烦- -就没写

  • 相关阅读:
    calendar.getTimeInMillis() 和 System.currentTimeMillis() 的区别
    微信小程序中使用 <web-view> 内嵌 H5 时,登录问题的处理方法
    小程序 TabBar 定制
    webpack 代码优化压缩方法
    react-router v4 按需加载的配置方法
    axios发送post请求,如何提交表单数据?
    react中键盘enter事件处理
    常用证件正则表达式
    react中input自动聚焦问题
    React Router v4 页面传值的三种方法
  • 原文地址:https://www.cnblogs.com/xuaidongstdudyrecording/p/7214703.html
Copyright © 2011-2022 走看看