首页 > 代码库 > C++ 文本查询2.0(逻辑查询)
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:\n"; 20 21 } else 22 { 23 os <<"\n"<< result.word_ << " appear " << result.lines_->size() 24 << (result.lines_->size() > 1 ? " times:" : " time:") << "\n\n"; 25 26 27 for (auto iter = result.lines_->cbegin(); 28 iter != result.lines_->cend(); iter = (result.lines_->upper_bound(*iter))) 29 { 30 os << "\t\t\t\t\t(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联合,太麻烦- -就没写
C++ 文本查询2.0(逻辑查询)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。