文本查询小例子---涉及多态 句柄类
来源:互联网 发布:ubuntu 12.04 安装jdk 编辑:程序博客网 时间:2024/06/08 02:52
最近实现了c++prime上的文本查询的小例子,见第四版15章最后一节。涉及到了多态,句柄类,故在此给出实现的源代码,以便后续查看。
一:系统要求:
图片无法上传---待传
二:代码
(1)queryWord.h ------------queryWorld是真正用来实现保存的数据结构及查询操作的。
#ifndef QUERYWORD#define QUERYWORD#include <map>#include <set>#include <vector>#include <string>#include <fstream>using namespace std;class QueryWord{public:typedef vector<string>::size_type line_no;void readFiles(ifstream &); // 将文本文件的内容读取到数据结构中set<line_no> run_query(const string&)const ; // 针对给定的string来查询结果void print(set<line_no> &, const string &str)const; // 将结果进行输出line_no size()const{return content.size();} private:string getLine(line_no) const;vector<string> content; // 用来保存读取的文本 每个string对应一行 因此下标就可以看做是行号了map<string, set<line_no> > textMap; // map 用来保存单词及该单词出现的行};#endif
queryWorld.cpp
#include <iostream>#include "queryWord.h"#include <sstream>#include "query.h"using namespace std;void QueryWord::readFiles(ifstream &infile){if(!infile){cout << "fail to load file" << endl;return;}string str;line_no line = 0;while(getline(infile, str)){content.push_back(str);// 采用istringstream来读取每个单词istringstream is(str);string word;while(is >> word){for(string::iterator iter = word.begin(); iter != word.end();){if(!isalnum(*iter))iter = word.erase(iter);else iter++;}textMap[word].insert(line);}line++;}}// 针对每个单词,返回该单词所对应的set集合 即为查询的单词所对应的行号set<QueryWord::line_no> QueryWord::run_query(const string &query_word)const{map<string, set<line_no> >::const_iterator iter = textMap.find(query_word);if(iter == textMap.end()) return set<line_no>();else return iter->second;}// 返回所对应行号所对应的内容string QueryWord::getLine(line_no line) const{return content[line];}void QueryWord::print(set<line_no> &result, const string &str)const{cout << str << " match occurs " << result.size() << " times:" << endl;for(set<QueryWord::line_no>::iterator iter = result.begin(); iter != result.end(); iter++){cout << "(line " << (*iter)+1 << ") " << getLine(*iter) << endl; }cout << endl;cout << "Executed Query for: ";}
(2)queryBase.h:查询的是基类,为抽象类 通过虚函数eval来实现得到查询的结果
// 查询的是基类,为抽象类 通过虚函数eval来实现得到查询的结果 //定义了句柄类Query,用来存储和管理基类指针 // #ifndef QUERYBASE#define QUERYBASE#include "queryWord.h"#include <iostream>using namespace std;class QueryBase{friend class Query;protected:typedef QueryWord::line_no line_no;virtual ~QueryBase(){} // 有虚函数要用虚析构函数 private:virtual set<line_no> eval(QueryWord &query_word)=0;};#endif
(3)query.h -------------句柄类,所有的操作都归并到操作句柄类,用来存储和管理基类指针
#ifndef QUERY#define QUERY#include "queryBase.h"#include <string>using namespace std;#include "wordQuery.h"class Query{public:friend Query operator&(Query&, Query&);friend Query operator|(Query&, Query&);friend Query operator~(Query&);Query():qb(NULL), p(new size_t(1)){} // 必须 有不然notWordQuery中成员变量无法定义Query(string&); // 得到一个wordQueryQuery(const Query &q):qb(q.qb), p(q.p){++*p;}; // 复制构造函数Query operator=(Query &q); // 赋值操作符set<QueryWord::line_no> eval(QueryWord &query_word){ return qb->eval(query_word);} // 利用的是多态 实质上调用的是各派生类的eval函数~Query(){deQuery();}private:void deQuery(){if(--*p == 0){delete qb, delete p;}}Query(QueryBase*);QueryBase *qb; // 基类指针size_t *p; // 计数指针};#endif
query.cpp
#include "query.h"Query Query::operator=(Query &q){++*q.p;deQuery();qb = q.qb;p = q.p;return *this;}Query::Query(string &word){qb = new WordQuery(word);p = new size_t(1);}Query::Query(QueryBase*q):qb(q), p(new size_t(1)){};
(4)派生类 --- 与或非及普通单词查询
wordQuery.h
#ifndef WORDQUERY#define WORDQUERY#include "queryBase.h"#include "queryWord.h"#include <iostream>using namespace std;class WordQuery:public QueryBase{friend class Query;WordQuery(string &word):queryWord(word){};set<line_no> eval(QueryWord &query_word){return query_word.run_query(queryWord);} //string queryWord;~WordQuery(){}};#endif
notWordQuery.h -----非
#ifndef NOTWORDQUERY#define NOTWORDQUERY#include "query.h"#include <iostream>using namespace std;class NotWordQuery:public QueryBase{friend Query operator~(Query &);NotWordQuery(Query &query):q(query){}set<line_no> eval(QueryWord &query_word);Query q;~NotWordQuery(){};};#endif
orWordQuery.h ----------或
#ifndef ORWORDQUERY#define ORWORDQUERY#include "binaryQuery.h"class OrWordQuery:public BinaryQuery{friend Query operator|(Query &, Query &);set<line_no> eval(QueryWord &query_word);OrWordQuery(Query &l, Query &r):BinaryQuery(l, r, string("|")){}};#endif
AndWordQuery.h -----------与
#ifndef ANDWORDQUERY#define ANDWORDQUERY#include "binaryQuery.h"class AndWordQuery:public BinaryQuery{friend Query operator&(Query &, Query &);set<line_no> eval(QueryWord &query_word);AndWordQuery(Query &l, Query &r):BinaryQuery(l, r, string("&")){}};#endif
wordQuery.cpp ----- 各派生类eval的实现
#include "notWordQuery.h"#include "queryWord.h"#include "andWordQuery.h"#include "orWordQuery.h"#include <iostream>#include <algorithm>#include <iterator>using namespace std;// 非操作符所对应的查询eval操作set<QueryWord::line_no> NotWordQuery::eval(QueryWord &query_word){ set<line_no> result = q.eval(query_word);set<line_no> ret_result;for(line_no i = 0; i < query_word.size(); i++){set<line_no>::iterator iter = result.find(i);if(iter == result.end()) ret_result.insert(i);}return ret_result;}// 与操作符所对应的查询eval操作set<QueryWord::line_no> OrWordQuery::eval(QueryWord &query_word){set<line_no> l = lhs.eval(query_word);set<line_no> r = rhs.eval(query_word);set<line_no> ret_result(l.begin(), l.end());ret_result.insert(r.begin(), r.end());return ret_result;}// 与操作符所对应的查询eval操作,使用了set_intersection来实现与操作set<QueryWord::line_no> AndWordQuery::eval(QueryWord &query_word){set<line_no> l = lhs.eval(query_word);set<line_no> r = rhs.eval(query_word);set<line_no> ret_result;set_intersection(l.begin(), l.end(),r.begin(), r.end(), inserter(ret_result, ret_result.begin()));return ret_result;}
(5)主函数Main.cpp
#include <iostream>#include "queryWord.h"#include "query.h"#include <fstream>#include "notWordQuery.h"#include "andWordQuery.h"#include "orWordQuery.h"#include <string>using namespace std;// 实质上调用了Query(QueryBase*)这个构造函数inline Query operator&(Query& l, Query& r){return new AndWordQuery(l, r);}inline Query operator|(Query&l, Query&r){return new OrWordQuery(l, r);}inline Query operator~(Query &q){return new NotWordQuery(q);}int main(){QueryWord qw;ifstream infile("F:\\11.txt");qw.readFiles(infile);string str;cout << "Executed Query for: ";/*while(cin >> str){Query q1(str);set<QueryWord::line_no> result = q1.eval(qw);qw.print(result, str);}*/cin >> str;Query q1(str);set<QueryWord::line_no> result1 = q1.eval(qw);qw.print(result1, str);cout << "~" << endl;Query q2 = ~q1;set<QueryWord::line_no> result2 = q2.eval(qw);qw.print(result2, str);cout << "&" << endl;Query q4 = q1 & q2;set<QueryWord::line_no> result3 = q4.eval(qw);qw.print(result3, str);return 0;}
三:运行结果
待上传....
0 0
- 文本查询小例子---涉及多态 句柄类
- 简单的文本查询和替换小例子
- 句柄类例子
- 两张链表查询 涉及多个字段查询
- ElasticSearch聚合查询小例子
- ORACLE 聚合查询小例子
- mysql数据库涉及多表查询
- 取得控件的句柄并使用的小例子
- 一个文本处理效率小例子
- python小例子之删除文本标签
- 通用SQL数据库查询语句/连接查询/多表连接查询 sql小例子
- 通用SQL数据库查询语句/连接查询/多表连接查询 sql小例子
- 多态的小例子
- c++11 文本查询练手小程序
- Hibernate中的HQL的基本常用小例子,单表查询与多表查询
- Hibernate的createSQLQuery查询的小例子
- Hibernate的createSQLQuery查询的小例子
- Hibernate的createSQLQuery查询的小例子
- 77自定义EditText用来复制粘贴(包括图片)
- MySQL for linux 安装使用指导说明书
- s3c6410-smdk6410.dts文件
- iOS 7 上如何实现苹果放弃的方法 sizeWithFont
- CocoaPods使用
- 文本查询小例子---涉及多态 句柄类
- 用js实现chexbox的全选和反选
- 解决gridview的Adapter中getview方法,当position==0的时候加载两次
- ListView的分页加载问题
- C#的值类型和引用类型
- iOS开发数据库篇—6.纯C写的一些SQLite常用的函数
- php-fpm---为每个开发人员分配进程
- SQL Server 2008数据类型
- 一次MySQL主从搭建出现“Last_IO_Errno: 1236”错误的处理记录