c++ 派生类 文本查询程序再探

Query_base类和Query类

//这是一个抽象基类,具体的查询类型从中派生,所有成员都是private的
class Query_base {friend class Query;protected:using line_no = TextQuery::line_no;//用于level函数virtual ~Query_base() = default;private://eval返回与当前Query匹配的QueryResultvirtual QueryResult eval(const TextQuery&) const = 0;//rep是表示查询 的一个stringvirtual std::string rep() const = 0;
};//这是一个管理Query_base继承体系的接口类
class Query{//这些运算符需要访问接受shared_ptr的构造函数,而该函数是私有的friend Query operator~(const Query &);friend Query operator|(const Query&,const Query&);friend Query operator&(const Query&,const Query&);public:Query(const std::string&);//构建一个新的WordQuery//接口函数:调用对应的Query_base操作QueryResult eval(const TextQuery &t) const{return q->eval(t);}std::string rep() const {return q->req();}private:Query(std::shared_ptr<Query_base> query):q(query){  }std::shared_ptr<Query_base> q;
};

Query的输出运算符

std::ostream & 
operator<<(std::ostream &os,const Query &query)
{//Query::rep通过它的Query_base指针对rep()进行虚调用return os<<query.rep();
}Query andq = Query(sought1) & Query(sought2);
cout<<andq<<endl;

派生类

class WordQuery: public Query_base {friend class Query; //Query使用WordQuery构造函数WordQuery(const std::string &s) : query_word(s) { }//具体的类:WordQuery将定义所有继承而来的纯虚函数QueryResult eval(const TextQuery &t) const{return t.query(query_word);}std::string rep() const {return query_word;}std::string query_word; //要查找的单词
};

NotQuery类及 ~运算符

class NotQuery : public Query_base {friend Query operator~(const Query &);NotQuery(const Query &q):query(q){ }//具体的类:NotQuery将定义所有继承而来的纯虚函数std::string rep() const {return "~(" + query.rep() + ")";}QueryResult eval(const TextQuery&) const;Query query;
};
inline Query operator~(const Query &operand)
{return std::shared_ptr<Query_base>(new NotQuery(oprand));
}//分配一个新的NotQuery对象
//将所得的NotQuery指针绑定到一个shared_ptr<Query_base>
shared_ptr<Query_base> tmp(new NotQuery(expr));
return Query(tmp);  //使用接受一个shared_ptr的Query构造函数

BinaryQuery类

class BinaryQuery : public Query_base{protected:BinaryQuery(const Query &l,const Query &r,std::string s):lhs(l),rhs(r),opSym(s){ }//抽象类:BinaryQuery不定义evalstd::string rep() const { return "(" + lhs.rep() + " " +opSym + ""  +rhs.rep() + ")";}Query lhs,rhs;  //左侧和右侧运算符对象std::string opSym;  //运算符名字
}

AndQuery类、OrQuery类及相应的运算符

    class AndQuery : public BinaryQuery {friend Query operator&(const Query&,const Query&);AndQuery(const Query &left,const Query &right) : BinaryQuery(left,right,"&"){ }//具体的类: AndQuery继承了rep并且定义了其他纯虚函数QueryResult eval(const TextQuery&) const;};inline Query operator&(const Query &lhs,const Query &rhs){return std::shared_ptr<Query_base>(new AndQuery(lhs,rhs));}class OrQuery : public BinaryQuery{friend Query operator|(const Query&,const Query&);OrQuery(const Query &left,const Query &right):BinaryQuery(left,right,"|"){ }QueryResult eval(const TextQuery&)const;};inline Query operator|(const Query &lhs,const Query &rhs){return std::shared_ptr<Query_base>(new OrQuery(lhs,rhs));}

eval函数

//返回运算对象查询结果set的并集
OrQuery::eval(const TextQuery& text) const
{//通过Query成员lhs和rhs进行的虚调用//调用eval返回每个运算对象的QueryResultauto right = rhs.eval(text),left = lhs.eval(text);//将左侧运算对象的行号拷贝到结果set中auto ret_lines =make_shared<set<line_no>>(left.begin(),left.end());//插入右侧运算对象所得的行号ret_lines->insert(right.begin(),right.end());//返回一个新的QueryResult,它表示lhs和rhs的并集return QueryResult(rep(),ret_lines,left.get_file());
}//返回运算对象查询结果set的交集
QueryResult
AndQuery::eval(const TextQuery& text) const
{//通过Query运算对象进行的虚调用,以获得运算对象的查询结果setauto left = lhs.eval(text),right = rhs.eval(text);//保存left 和 right交集的setauto ret_lines =  make_shared<set<line_no>>();//将两个范围的交集写入一个目的迭代器中//本次调用的目的迭代器向ret添加元素set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*ret_lines,ret_lines->begin()));return QueryResult(rep(),ret_lines,left.get_file());
}//返回运算对象的结果set中不存在的行
QueryResult
NotQuery::eval(const TextQuery& text) const
{//通过Query运算对象对eval进行虚调用auto result = query.eval(text);//开始时结果set为空auto ret_lines = make_shared<set<line_no>>();//我们必须在运算对象出现的所有行中进行迭代auto beg = result.begin(),end = result.end();//对于输入文件的每一行,如果该行不在result当中,则将其添加到ret_linesauto sz = result.get_file()->size();for(size_t n = 0;n != sz; ++n){//如果我们还没有处理完result的所有行//检查当前行是否存在if(beg = end || *beg != n)ret_lines->insert(n);   //如果不在result当中,添加这一行else if(beg != end)++beg;  //否则继续获取result的下一行(如果有的话)}return QueryResult(rep(),ret_lines,result.get_file());
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/16544.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#文件操作从入门到精通(2)——查看某个dll中有哪些函数

kernel32.dll中含有ini文件操作使用的函数,我们可以通过VisualStudio自带的dumpbin.exe查看dll所包含的函数,操作步骤如下: 1、找到dumpbin.exe所在的文件夹 我的电脑中安装了VisualStudio2019社区版以及VisualStudio2017Professional,但是我发现VisualStudio2019社区版中…

spring项目中idea提示Application context not configured for this file

今天在重构项目的时候&#xff0c;碰到一个问题。就是在spring底下&#xff0c;有一个包里面的所有配置类&#xff0c;在idea的开发工具类底下提示&#xff0c;Application context not configured for this file&#xff0c;如图所示 一开始以为是警告&#xff0c;不予处理&am…

大数据课程E7——Flume的Interceptor

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解Interceptor的概念和配置参数&#xff1b; ⚪ 掌握Interceptor的使用方法&#xff1b; ⚪ 掌握Interceptor的Host Interceptor&#xff1b; ⚪ 掌握Interceptor的…

MySQL中的函数

系列文章目录 MySQL常见的几种约束 文章目录 系列文章目录前言一、单行函数1.字符串函数 &#xff08;String StringBuilder&#xff09;2.数值函数 &#xff08;Math&#xff09;3.日期与时间函数4.流程函数&#xff08; IF SWITCH&#xff09;5.JSON函数6.其他函数 二、多行…

TreeMap的底层实现

0. 你需要知道的TreeMap的内置属性 0.1 节点属性 K key; // 键 V value; // 值 Entry<K,V> left; // 左子节点 Entry<K,V> right; // 右子节点 Entry<K,V> parent; // 父节点 boolean color; // 节点的颜色0.2 成员变量 //比较器对象private f…

rsync下行同步+inotify实时同步部署

目录 一、rsync简介 1.2 同步方式 1.2.1 全量备份 1.2.2 增量备份 1.2.3 差量备份 1.3 rsync的特点 1.4 rsync的优势与不足 1.5 rsync与cp、scp对比 1.6 rsync同类服务 二、rsync源服务器的关系 三、配置rsync源 3.1 基本思路 3.2 配置文件rsyncd.conf 3.3 独立…

代码随想录算法训练营19期第2天| 滑动窗口,螺旋矩阵模拟 (二刷)

【滑动窗口&#xff1a;209 长度最小子数组 904.水果成篮 76.最小覆盖子串】 209长度最小子数组 sum要达到target&#xff0c;自己滑动窗口法ac&#xff0c;不断往前囊括新的一个&#xff0c;然后试着从头减少一个个&#xff0c;看sum还够不够 mycode&#xff1a; int minS…

HDFS Erasure coding-纠删码介绍和原理

HDFS Erasure coding-纠删码介绍和原理 三副本策略弊端Erasure Coding&#xff08;EC&#xff09;简介Reed- Solomon&#xff08;RS&#xff09;码 EC架构 三副本策略弊端 为了提供容错能力&#xff0c;hdfs回根据replication factor&#xff08;复制因子&#xff09;在不同的…

ZooKeeper 选举的过半机制防止脑裂

结论&#xff1a; Zookeeper采用过半选举机制&#xff0c;防止了脑裂。 原因&#xff1a; 如果有5台节点&#xff0c;leader联系不上了&#xff0c;其他4个节点由于超过半数&#xff0c;所以又选出了一个leader&#xff0c;当失联的leader恢复网络时&#xff0c;发现集群中已…

idea application.yml配置文件没有提示或读不到配置

1.首先确定你的resources文件夹正常且yml文件图表和下面一样 不一样的右键去设置 2.确保你已经缩进了且层级关系正常 3.如果以上都不是&#xff0c;先考虑删除.idea重开试试 4.以上解决不了就装以下两个插件解决

目标检测之3维合成

现在有一系列的图片&#xff0c;图片之间可以按照z轴方向进行排列。图片经过了目标检测&#xff0c;输出了一系列的检测框&#xff0c;现在的需求是将检测框按类别进行合成&#xff0c;以在3维上生成检测结果。 思路&#xff1a;将图片按照z轴方向排列&#xff0c;以z轴索引作…

微分流形2:流形上的矢量场和张量场

来了来了&#xff0c;切向量&#xff0c;切空间。流形上的所有的线性泛函的集合&#xff0c;注意是函数的集合。然后取流形上的某点p&#xff0c;它的切向量为&#xff0c;线性泛函到实数的映射。没错&#xff0c;是函数到实数的映射&#xff0c;是不是想到了求导。我们要逐渐熟…

java源码-List源码解析

Java中的List是一个接口&#xff0c;它定义了一组操作列表的方法。List接口的常见子类包括ArrayList、LinkedList和Vector等。 以下是Java中List接口及其常见方法的源码解析&#xff1a; 1. List接口定义 public interface List<E> extends Collection<E> { …

Django模型将模型注释同步到数据库

1、安装django-comment-migrate库 pip install django-comment-migrate 2、将库注册到settings.py文件中 INSTALLED_APPS [...django_comment_migrate, # 表注释... ] 3、加注释 3.1、给模型&#xff08;表&#xff09;加注释 在模型的class Meta中编辑 verbose_name&…

Go和Java实现适配器模式

Go和Java实现适配器模式 我们通过下面的实例来演示适配器模式的使用&#xff0c;其中&#xff0c;音频播放器设备只能播放 mp3 文件&#xff0c;通过使用一个更高级 的音频播放器来播放 vlc 和 mp4 文件。 1、适配器模式 适配器模式是作为两个不兼容的接口之间的桥梁。这种…

UML/SysML建模工具更新(2023.7)(1-5)有国产工具

DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 最近一段时间更新的工具有&#xff1a; 工具最新版本&#xff1a;Visual Paradigm 17.1 更新时间&#xff1a;2023年7月11日 工具简介 很用心的建模工具。支持编写用例规约。支持文本分析和C…

kafka怎么用代码读取数据

Kafka可以通过Java语言中的Kafka客户端库来读取数据。以下是一个简单的Java代码示例&#xff0c;通过Kafka Consumer API从Kafka集群中读取数据&#xff1a; java import java.util.Properties; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.…

TCP三次握手和四次挥手以及11种状态(二)

11种状态 1、一开始&#xff0c;建立连接之前服务器和客户端的状态都为CLOSED&#xff1b; 2、服务器创建socket后开始监听&#xff0c;变为LISTEN状态&#xff1b; 3、客户端请求建立连接&#xff0c;向服务器发送SYN报文&#xff0c;客户端的状态变味SYN_SENT&#xff1b; 4、…

数据结构---树和二叉树

这里写目录标题 树和二叉树的定义树的定义树的基本术语线性结构和树形结构的比较二叉树的定义起因定义 案例引入前缀码编码表达式的实现二叉树的抽象类型定义 二叉树的性质和存储结构二叉树的性质二叉树的特殊形式满二叉树完全二叉树 完全二叉树的两个性质二叉树的存储结构顺序…

ubuntu目录分析

在Ubuntu根目录下&#xff0c;以下是一些常见文件夹的含义&#xff1a; /bin&#xff1a;存放可执行文件&#xff0c;包含一些基本的命令和工具。 /boot&#xff1a;存放启动时所需的文件&#xff0c;如内核和引导加载程序。 /dev&#xff1a;包含设备文件&#xff0c;用于与硬…