博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ Primer中文本查询演示样例Query的实现
阅读量:6983 次
发布时间:2019-06-27

本文共 6966 字,大约阅读时间需要 23 分钟。

近期在看C++ Primer复习C++的语法,看到书中15.9章中的文本查询演示样例时,认为设计得非常不错,于是便动手照着实现了一个,改动了非常久最终执行成功了,从中也学习到了非常多的语法。以下把实现与总结分享给大家:

首先是在10.6.2节中实现的TextQuery类:

TextQuery.h#ifndef __TestC____TextQuery__#define __TestC____TextQuery__#include 
#include
#include
#include
using namespace std;class TextQuery {public: typedef vector
::size_type line_no; TextQuery(string[], vector
::size_type); set
run_query(const string&) const; line_no size() const;private: vector
lines_of_text;};#endif /* defined(__TestC____TextQuery__) */
TextQuery.cpp#include "TextQuery.h"TextQuery::TextQuery(string strArray[], vector
::size_type count) { lines_of_text.assign(strArray, strArray+count);}set
TextQuery::run_query(const string&word) const { set
ret_lines; for (int i=0;i
接下来是查询类的句柄类Query:

Query.h#ifndef __TestC____Query__#define __TestC____Query__#include 
#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
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
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 
#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
eval(const TextQuery&) const = 0; virtual ostream & display(ostream & = cout) const = 0;};class WordQuery : Query_base { friend class Query; WordQuery(const string &); set
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
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
eval(const TextQuery&) const;};class OrQuery : BinaryQuery { friend Query operator|(const Query&, const Query&); OrQuery(Query left, Query right); set
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::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::eval(const TextQuery &file) const { set
has_val = query.eval(file); set
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::eval(const TextQuery&file) const { set
left = lhs.eval(file), right = rhs.eval(file); set
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::eval(const TextQuery&file) const { set
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
::size_type> result = q.eval(TextQuery(article, sizeof(article)/sizeof(article[0]))); for (set
::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几个类的构造函数都是私有的,因此必须将使用到这几个类的函数声明为友元函数,在本例中为&、|、~几个操作符函数。

假设大家认为对自己有帮助的话,还希望能帮顶一下,谢谢:)
个人博客:
本文地址:
转载请注明出处,谢谢!
你可能感兴趣的文章
Django搭建个人博客:上传头像图片
查看>>
Docker与自动化测试及其测试实践
查看>>
Java-集合的简单介绍
查看>>
分布式架构发展
查看>>
针对不同的系统的宏定义
查看>>
十分钟熟练Dockerfile指令
查看>>
ES6新特征总结与介绍——声明与表达式
查看>>
python3实现抓取网页资源的 N 种方法(内附200GPython学习资料)
查看>>
不用软件,手动修复双系统引导进win7,xp的多种方法
查看>>
python 访问需要HTTP Basic Authentication认证的资源
查看>>
java中比较字符串的大小用String的compareTo()
查看>>
plist使用
查看>>
Linux RAR 安装和使用
查看>>
【OC】【一秒就会】【collectionView 头部吸住功能】
查看>>
51CTO下载 好资料分享
查看>>
linux 下转换UTC到本地时间
查看>>
Linux的起源与各发行版的基本知识
查看>>
单播包、广播包、组播包、洪泛包
查看>>
iptables命令结构之命令
查看>>
RabbitMQ之Exchange分类
查看>>