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());
}
相关文章:
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返回与…...
17. 电话号码的字母组合
题目描述 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits "23" …...
Redis 基础知识和核心概念解析:理解 Redis 的键值操作和过期策略
🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~ἳ…...
Jenkins中sh函数的用法
在Jenkins的Pipeline中,sh函数的用法 用法一 单个命令字符串包括使用,示例如下: sh echo "Hello, Jenkins!"用法二 多个命令字符串包括命令列表使用,示例如下: sh echo "Step 1" echo "…...
Android 之 Canvas API 详解 (Part 3) Matrix 和 drawBitmapMesh
本节引言: 在Canvas的API文档中,我们看到这样一个方法:drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) 这个Matrix可是有大文章的,前面我们在学Paint的API中的ColorFilter中曾讲过ColorMatrix 颜色矩阵,一个4…...
基于Ubuntu 22.04 编译chip-tool工具
前言 编译过程有点曲折,做下记录,过程中,有参考别人写的博客,也看github 官方介绍,终于跑通了~ 环境说明: 首先需要稳定的梯子,可以访问“外网”ubuntu 环境,最终成功实验在Ubunt…...
opencv-17 脸部打码及解码
使用掩模和按位运算方式实现的对脸部打码、解码实例 代码如下: import cv2 import numpy as np #读取原始载体图像 lenacv2.imread("lena.png",0) #读取原始载体图像的 shape 值 r,clena.shape masknp.zeros((r,c),dtypenp.uint8) mask[220:400,250:350…...
JVM分享
JVM分享 官网:https://docs.oracle.com/javase/specs/jvms/se8/html/index.html Java代码的执行流程 我们编写完之后的java文件如果要运行,java文件会编译成class文件,在jvm中运行时ClassLoader会加载class文件,加载进来之后&a…...
Apache Dubbo CVE-2021-36162 挖掘过程
01 漏洞背景 发现该漏洞的起因是在分析 CVE-2021-30181 的脚本注入补丁的时候,意外发现了几个已被修复的 yaml 反序列化漏洞,还以为是未公开的Nday,查询后发现其实对应的是 CVE-2021-30180 漏洞的修复代码。通过查看补丁可以知道,…...
开源框架面试题目整理
目录 SpringIOC SpringAOP Spring的生命周期 Spring Bean作用域 Spring Bean作用域并发安全 Spring循环依赖...
Mr. Cappuccino的第52杯咖啡——Mybatis环境搭建与使用
Mybatis环境搭建与使用 Mybatis介绍Mybatis环境搭建与使用基于XML方式-原生方式开发创建数据库表项目准备项目结构项目代码实体类中添加有参构造方法产生的问题 基于XML方式-mapper代理开发项目准备项目结构项目代码SQL映射文件中namespace未设置为接口全限定名产生的问题 基于…...
了解Unity编辑器之组件篇Tilemap(五)
Tilemap:用于创建和编辑2D网格地图的工具。Tilemap的主要作用是简化2D游戏中地图的创建、编辑和渲染过程。以下是一些Tilemap的主要用途: 2D地图绘制:Tilemap提供了一个可视化的编辑器界面,可以快速绘制2D地图,例如迷…...
Linux字符设备操作函数
Linux字符设备操作函数是指对字符设备进行打开、关闭、读取、写入、控制等基本操作的函数,它们通过字符设备结构体中的 file_operations 结构体来定义。常用的字符设备操作函数包括: 1、open: 当一个进程试图打开设备文件时,调用这个函数。开…...
吉林大学计算机软件考研经验贴
文章目录 简介政治英语数学专业课 简介 本人23考研,一战上岸吉林大学软件工程专硕,政治72分,英一71分,数二144分,专业课967综合146分,总分433分,上图: 如果学弟学妹需要专业课资料…...
2023-07-26力扣每日一题-区间翻转线段树
链接: 2569. 更新数组后处理求和查询 题意: 给两个等长数组nums1和nums2,三个操作: 操作1:将nums1的[l,r]翻转(0变1,1变0) 操作2:将nums2[any]变成nums2[any]nums1[any]*p&…...
Java设计模式之 -- 桥接模式
什么是桥接模式 桥接模式是一种结构型设计模式,也被称为“Handle/Body”。这种设计模式主要用于将抽象部分与它的实现部分分离,使它们可以独立地变化。这种方式有助于减少系统中的耦合性,增加了扩展性。 主要解决什么问题 桥接模式主要解决…...
【node.js】02-path模块
目录 1. path.join() 2. path.basename() 3. path.extname() 1. path.join() 使用 path.join() 方法,可以把多个路径片段拼接为完整的路径字符串,语法格式如下: path.join([...paths]) 例子: const path require(path)co…...
攻防世界-Reverse-re1
题目描述:菜鸡开始学习逆向工程,首先是最简单的题目 下载附件,执行程序,如下界面 1. 思路分析 没啥说的,既然题目都说是一道简单的逆向题,那么直接使用ida逆向即可,看逆向出的结果是否能写入到…...
AES加密的基本常识和封装类
AES加密的基本常识和封装类 AES(Advanced Encryption Standard)是一种对称密钥加密算法,被广泛用于保护敏感数据的安全性。它是一种块加密算法,意味着它将明文数据分成固定大小的块,并使用相同的密钥对每个块进行独立…...
elasticsearch使用记录
参考文章:https://elasticsearch-py.readthedocs.io/en/v8.8.2/ 参考文章:https://cuiqingcai.com/6214.html 参考文章:https://www.cnblogs.com/cupleo/p/13953890.html elasticsearch版本:8.8.2(软件包发行版) python版本&#…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
