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版本&#…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
