C++ Primer中文本查询演示样例Query的实现
近期在看C++ Primer复习C++的语法,看到书中15.9章中的文本查询演示样例时,认为设计得非常不错,于是便动手照着实现了一个,改动了非常久最终执行成功了,从中也学习到了非常多的语法。以下把实现与总结分享给大家:
首先是在10.6.2节中实现的TextQuery类:
TextQuery.h #ifndef __TestC____TextQuery__
#define __TestC____TextQuery__ #include <iostream>
#include <vector>
#include <set>
#include <map> using namespace std; class TextQuery {
public:
typedef vector<string>::size_type line_no; TextQuery(string[], vector<string>::size_type);
set<line_no> run_query(const string&) const;
line_no size() const;
private:
vector<string> lines_of_text;
}; #endif /* defined(__TestC____TextQuery__) */
TextQuery.cpp
#include "TextQuery.h"
TextQuery::TextQuery(string strArray[], vector<string>::size_type count) {
lines_of_text.assign(strArray, strArray+count);
}
set<TextQuery::line_no> TextQuery::run_query(const string&word) const {
set<line_no> ret_lines;
for (int i=0;i<lines_of_text.size();i++) {
string line = lines_of_text[i];
if (line.find(word) != string::npos) {
ret_lines.insert(i);
}
}
return ret_lines;
}
TextQuery::line_no TextQuery::size() const {
return lines_of_text.size();
}
接下来是查询类的句柄类Query:
Query.h #ifndef __TestC____Query__
#define __TestC____Query__ #include <iostream>
#include "TextQuery.h" class Query_base; 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 &);
virtual ~Query();
Query& operator=(const Query&); set<TextQuery::line_no> eval(const TextQuery&) const;
ostream & display(ostream &) const;
private:
Query(Query_base *); Query_base *q;
size_t *use;
void decr_use();
}; inline ostream & operator<<(ostream &os, const Query &q) {
return q.display(os);
} #endif /* defined(__TestC____Query__) */
Query.cpp #include "Query.h"
#include "Query_base.h" Query::Query(const Query &c) : q(c.q), use(c.use) {
++*use;
} Query::Query(const string &s) : q(new WordQuery(s)), use(new size_t(1)) { } Query::Query(Query_base *query) : q(query), use(new size_t(1)) { } Query::~Query() {
decr_use();
} void Query::decr_use() {
if (--*use == 0) {
delete q;
delete use;
}
} set<TextQuery::line_no> Query::eval(const TextQuery &t) const{
return q->eval(t);
} ostream& Query::display(ostream &os) const {
return q->display(os);
}
接下来是最核心的各个查询类Query_base、WordQuery、NotQuery、AndQuery、OrQuery:
Query_base.h #ifndef __TestC____Query_base__
#define __TestC____Query_base__ #include <iostream>
#include "TextQuery.h"
#include "Query.h" class Query_base {
friend class Query;
protected:
typedef TextQuery::line_no line_no;
virtual ~Query_base() {}
private:
virtual set<line_no> eval(const TextQuery&) const = 0;
virtual ostream & display(ostream & = cout) const = 0;
}; class WordQuery : Query_base {
friend class Query;
WordQuery(const string &);
set<line_no> eval(const TextQuery&) const;
ostream & display(ostream & = cout) const; string query_word;
}; class NotQuery : public Query_base {
friend Query operator~(const Query &); NotQuery(Query);
set<line_no> eval(const TextQuery&) const;
ostream & display(ostream & = cout) const;
const Query query;
}; class BinaryQuery : public Query_base {
protected:
BinaryQuery(Query left, Query right, string op);
ostream & display(ostream & = cout) const; const Query lhs, rhs;
const string oper;
}; class AndQuery : BinaryQuery {
friend Query operator&(const Query&, const Query&);
AndQuery(Query left, Query right);
set<line_no> eval(const TextQuery&) const;
}; class OrQuery : BinaryQuery {
friend Query operator|(const Query&, const Query&);
OrQuery(Query left, Query right);
set<line_no> eval(const TextQuery&) const;
}; #endif /* defined(__TestC____Query_base__) */
Query_base.cpp #include "Query_base.h" /**
* WordQuery
*/ WordQuery::WordQuery(const string &s) : query_word(s) { } set<WordQuery::line_no> WordQuery::eval(const TextQuery &t) const {
return t.run_query(query_word);
} ostream & WordQuery::display(ostream &os) const {
return os << query_word;
} /**
* NotQuery
*/ NotQuery::NotQuery(Query q) : query(q) { } set<NotQuery::line_no> NotQuery::eval(const TextQuery &file) const {
set<line_no> has_val = query.eval(file);
set<line_no> ret_lines; for (TextQuery::line_no n = 0; n != file.size(); ++n) {
if (has_val.find(n) == has_val.end()) {
ret_lines.insert(n);
}
}
return ret_lines;
} ostream & NotQuery::display(ostream &os) const {
return os << "~(" << query << ")";
} /**
* BinaryQuery
*/ BinaryQuery::BinaryQuery(Query left, Query right, string op) : lhs(left), rhs(right), oper(op) { } ostream & BinaryQuery::display(ostream &os) const {
return os << "(" << lhs << " " << oper << " "
<< rhs << ")";
} /**
* AndQuery
*/ AndQuery::AndQuery(Query left, Query right) : BinaryQuery(left, right, "&") { } set<AndQuery::line_no> AndQuery::eval(const TextQuery&file) const {
set<line_no> left = lhs.eval(file), right = rhs.eval(file);
set<line_no> ret_lines;
set_intersection(left.begin(), left.end(),
right.begin(), right.end(),
inserter(ret_lines, ret_lines.begin()));
return ret_lines;
} /**
* OrQuery
*/ OrQuery::OrQuery(Query left, Query right) : BinaryQuery(left, right, "|") { } set<OrQuery::line_no> OrQuery::eval(const TextQuery&file) const {
set<line_no> right = rhs.eval(file), ret_lines = lhs.eval(file);
ret_lines.insert(right.begin(), right.end());
return ret_lines;
}
以下是以上代码的使用方法演示样例:
main.cpp #include "Query.h"
#include "Query_base.h" using namespace std; inline Query operator~(const Query &oper) {
return new NotQuery(oper);
} inline Query operator|(const Query &left, const Query &right) {
return new OrQuery(left, right);
} inline Query operator&(const Query &left, const Query &right) {
return new AndQuery(left, right);
} int main(int argc, const char * argv[])
{
string article[] = {
"Alice Emma has long flowing red hair.",
"Her Daddy says when the wind blows",
"through her hair, it looks almost alive,",
"like a fiery bird in flight",
"A beautiful fiery bird, he tells her,",
"magical but untamed.",
"\"Daddy, shush, there is no such thing,\"",
"she tells him, at the same time wanting",
"him to tell her more.",
"Shyly, she asks, \"I mean, Daddy, is there?\""
}; Query q = ~(Query("fiery") & Query("bird") | Query("wind"));
set<vector<string>::size_type> result = q.eval(TextQuery(article, sizeof(article)/sizeof(article[0])));
for (set<vector<string>::size_type>::iterator iter = result.begin(); iter != result.end(); iter++) {
cout << *iter+1 << endl;
}
return 0;
}
以上代码中须要注意的语法点有:
1. Query的几个重载操作符假设作为inline函数的话,必须放在定义的头文件或者用到重载操作符的实现文件里,在本例中假设放在Query.h文件里,因为须要引入Query_base.h文件,会导致头文件循环引用的问题,因此放在了main函数中。<<操作符因为没有使用其它类,所以能够放在Query_base.h文件里。
2. 因为NotQuery、OrQuery、AndQuery几个类的构造函数都是私有的,因此必须将使用到这几个类的函数声明为友元函数,在本例中为&、|、~几个操作符函数。
C++ Primer中文本查询演示样例Query的实现的更多相关文章
- 01_MUI之Boilerplate中:HTML5演示样例,动态组件,自己定义字体演示样例,自己定义字体演示样例,图标字体演示样例
1安装HBuilder5.0.0,安装后的界面截图例如以下: 2 依照https://www.muicss.com/docs/v1/css-js/boilerplate-html中的说明,创建上 ...
- 在VC6.0中多线程编程演示样例(带同步信号量)
直接上代码: #include <windows.h>//必要的头文件,使用Windows API函数 #include <stdio.h> int index = 0; in ...
- 一步一步跟我学习lucene(18)---lucene索引时join和查询时join使用演示样例
了解sql的朋友都知道,我们在查询的时候能够採用join查询,即对有一定关联关系的对象进行联合查询来对多维的数据进行整理.这个联合查询的方式挺方便的.跟我们现实生活中的托人找关系类似,我们想要完毕一件 ...
- SQL SEVER 2008中的演示样例数据库
SQL SEVER 2008数据库是什么我就不说了,我在这里分享一下怎样学习SQL SEVER 2008数据库,假设是对数据库或是SQL SEVER 数据库全然陌生或是不熟悉的人来说,建议看看一些视频 ...
- 让你提前认识软件开发(19):C语言中的协议及单元測试演示样例
第1部分 又一次认识C语言 C语言中的协议及单元測试演示样例 [文章摘要] 在实际的软件开发项目中.常常要实现多个模块之间的通信.这就须要大家约定好相互之间的通信协议,各自依照协议来收发和解析消息. ...
- Android中MVP模式与MVC模式比較(含演示样例)
原文链接 http://sparkyuan.me/ 转载请注明出处 MVP 介绍 MVP模式(Model-View-Presenter)是MVC模式的一个衍生. 主要目的是为了解耦,使项目易于维护. ...
- ListView中pointToPosition()方法使用具体演示样例
MainActivity例如以下: package cc.testpointtoposition; import java.util.ArrayList; import java.util.HashM ...
- 源代码方式向openssl中加入新算法完整具体步骤(演示样例:摘要算法SM3)【非engine方式】
openssl简单介绍 openssl是一个功能丰富且自包括的开源安全工具箱.它提供的主要功能有:SSL协议实现(包括SSLv2.SSLv3和TLSv1).大量软算法(对称/非对称/摘要).大数运算. ...
- 关于 underscore 中模板引擎的应用演示样例
//关于 underscore 中模板引擎的应用演示样例 <!doctype html> <html> <head> <meta charset=" ...
随机推荐
- 实验数据结构——KMP算法Test.ming
翻译计划 小明初学者C++,它确定了四个算术.关系运算符.逻辑运算.颂值操作.输入输出.使用简单的选择和循环结构.但他的英语不是很好,记住太多的保留字,他利用汉语拼音的保留字,小屋C++,发明 ...
- Lua之Lua数据结构-TTLSA(6)(转) good
一. tabletable是lua唯一的数据结构.table 是 lua 中最重要的数据类型. table 类似于 python 中的字典.table 只能通过构造式来创建.其他语言提供的其他数据结构 ...
- android cocos2dx游戏-加入截图和分享微博功能
本文介绍怎样在游戏中添加分享功能,截屏后分享到微博及其他社交网络的功能. public class ShareSupport { // when you want to use share(),fir ...
- 在Ceph创建虚拟机的过程改进分析
作为个人学习笔记分享.有不论什么问题欢迎交流! 近期在Gerrit中看到一个change:https://review.openstack.org/#/c/94295/ , 它主要是对当前在Ceph中 ...
- 单元测试React
React单元测试——十八般兵器齐上阵,环境构建篇 一个完整.优秀的项目往往离不开单元测试的环节,就 github 上的主流前端项目而言,基本都有相应的单元测试模块. 就 React 的项目来说,一套 ...
- DBA查询命令积累——不断更新
原文:DBA查询命令积累--不断更新 一.服务器配置: 1.兼容级别:兼容级别只影响指定数据库中的行为,而不会影响整个服务器上的行为. 1.1.查看数据库兼容级别及更改兼容级别: SELECT com ...
- 用python做oj上的简单题(持续更新中.......)
本人刚開始接触python,在oj上解一些简单的题,欢迎交流,不喜勿喷. OJ地址链接:acm.sdut.edu.cn http://acm.sdut.edu.cn/sdutoj/showproble ...
- 解决win10开机出现C:\WIndows\system32\config\systemprofile\Desktop不可用 问题
背景:公司一台win10机子好久没用了,今天开了打算用下(打算远程桌面),远程桌面连不上(好久没用了,用户名都忘了),所以又插上显示器和键鼠. 键盘因为是PS/2接口,不能热插拔,所以开机一段时间后( ...
- 编写高性能Javascript
编写高性能Javascript 多年来,Javascript一直在web应用开发中占据重要的地位,但是很多开发者往往忽视一些性能方面的知识,特别是随着计算机硬件的不断升级,开发者越发觉得Javascr ...
- Docker简明教程(转)
Docker自从诞生以来就一直备受追捧,学习Docker是一件很炫酷.很有意思的事情.我希望通过这篇文章能够让大家快速地入门Docker,并有一些学习成果来激发自己的学习兴趣.我也只是一个在Docke ...