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

这篇具有很好参考价值的文章主要介绍了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匹配的QueryResult
    virtual QueryResult eval(const TextQuery&) const = 0;
    //rep是表示查询 的一个string
    virtual 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不定义eval
    std::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返回每个运算对象的QueryResult
    auto 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运算对象进行的虚调用,以获得运算对象的查询结果set
    auto left = lhs.eval(text),right = rhs.eval(text);
    //保存left 和 right交集的set
    auto 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_lines
    auto 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());
}

文章来源地址https://www.toymoban.com/news/detail-620382.html

到了这里,关于c++ 派生类 文本查询程序再探的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据库原理-数据查询 单表查询【二】

    聚集函数: 统计元组个数 COUNT(*) 统计一列中值的个数 COUNT([DISTINCT|ALL]列名) 计算一列值的总和(此列必须为数值型) SUM([DISTINCT|[ALL]列名) 计算一列值的平均值(此列必须为数值型) AVG([DISTINCT|ALL]列名) 求一列中的最大值和最小值 MAX([DISTINCT|ALL]列名) MIN([DISTINCT|ALL]列名) 查询学

    2024年02月03日
    浏览(45)
  • PHP:数据库中设置文本长度,通过js去限制前台文本长度。扩展:数据类型的限制

     效果图  如上图:当测试111的长度超过数据库中限制的长度,进行提示,并且自动将多余部分截掉 HTML代码 JS功能实现代码 扩展:数据类型的限制 默认对int,varchar,datetime进行限制 功能实现 注:这里会出现时间选择器不能立刻进行展示,需要二次点击才能出现 ,解决方法:

    2024年02月13日
    浏览(47)
  • 大学数据库创建与查询实战——查询

    目录 查询表中指定的字段   查询表中的某一个字段的语法格式为: (一) (二)  GROUP BY 子句 (三) ORDER BY :对查询结果进行排序: 头歌实验 (四) (五)   查询表中的某一个字段的语法格式为: SELECT 列名 FROM 表名 ; 不同字段名称之间用逗号“,”分隔开,最后一

    2024年02月10日
    浏览(46)
  • 数据库的简单查询——单表查询

    本篇文章主要是数据库的一些简单查询,包括条件查询,模糊查询,分组查询等 准备工作:三张数据表                学生表(student):                            课程表(course):          学生选课表(sc):     (1)查询学生表中全体学生的所有信息。 SQL语句:

    2023年04月11日
    浏览(46)
  • java查询数据库百万条数据,优化之:多线程+数据库

    今天去面试时hr问了个关于大量数据查询的问题。 面试官:“我们公司是做数据分析的,每次需要从数据库中查询100万条数据进行分析,该接口不能用分页(不限制具体怎么实现),请问怎么优化sql或者java代码呢??” 如果用普通查询需要5分多分钟才查询完毕,所以我们用

    2024年02月15日
    浏览(53)
  • MySQL数据库:数据库的约束以及数据的聚合、联合查询

    目录 一.关系模型的简要概述 二.数据库的约束  2.1约束类型         2.2NULL约束 2.3 UNIQUE:唯一约束 2.4 默认约束 2.5 PRIMARY KEY:主键约束 2.6 FOREIGN KEY:外键约束 2.7 CHECK约束 三.高效率查询 3.1高效率查询的分类 3.2聚合查询 3.2.1聚合函数 3.2.2 GROUP BY子句 3.2.3HAVING 3.3.联合查询

    2024年02月10日
    浏览(67)
  • 数据库实验一:基本表操作、基本数据查询和复杂数据查询

    按下图创建四个表:teacher、student、course和SC,为属性选择合适的域、合适的主码和外键约束,并为他们插入所列出数据; 中文语义 teacher (TID,TNAME,DEPT,SALARY) 教师(教工号,姓名,系,薪水) student (SID,SNAME,DEPT,AGE,GENDER) 学生(学号,姓名,系,年龄,性别) course (CID,CNAME,DE

    2024年02月01日
    浏览(64)
  • 【数据库】日常使用PL/SQL 登录ORACLE 数据库查询数据

    一、PL/SQL 登录方式 username: ##访问数据库的账号 password: ##访问数据库的密码 Databse: ##数据库IP地址/实例名 数据库集群心跳地址/实例名 Connect as : ##Normal,如果使用sysdba账户登录选择SYSDBA 二、PL/SQL使用SQL语句查询 点击上方导航栏,New,选择SQL Window,即可再次输入要查询的

    2024年02月19日
    浏览(70)
  • 关系数据库SQL数据查询

    1.查询仅涉及一个表,选择表中的若干列 查询全部列 选出所有属性列: 在SELECT后面列出所有列名 将目标列表达式指定为 * 查询经过计算的值 SELECT子句的目标列表达式不仅可以为表中的属性列,也可以是表达式 使用列别名改变查询结果的列标题: 2.选择表中的若干元组

    2024年02月09日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包