C++学习之第十七天-再探文本查询-实现与、或、非查询方法

本文介绍了使用C++实现文本查询功能,包括对单个单词的查询、NotQuery(查询未出现单词的句子)、AndQuery(查询两个单词同时出现的行的交集)和OrQuery(查询两个单词出现的行的并集)。通过抽象基类Query_base和派生类的设计,实现了灵活的查询操作。示例展示了不同查询的运行结果。
摘要由CSDN通过智能技术生成

        代码的实现基本是手敲一遍C++ Primer5 15.9文本查询再探,进一步巩固,继承、抽象基类、虚函数等等知识点。

面向对象程序设计

基于Day14天的文本查询进行扩展:

        TextQuery类:该类中有个query查询操作,返回一个结果存在QueryResult中

        QueryResult类:保存一个单词的查询结果:单词、行号集合、句子集合

1.Query_base_抽象层,提供抽象接口。

        虚函数eval:接受一个TextQuery,返回结果存储在QueryResult对象中,eval函数主要在业务层Query_base中实现,eval函数在不同的派生类中重写,返回不一样的结果。

2.Query类--实现层,提供用户外部接口,用于隐藏整个继承体系。

        1.Query类提供一个指向Query_base智能指针p,用该指针绑定到Query_base的派生类身上,用户通过对Query对象的操作,间接地创建并且处理Query_base对象。

        2.Query有一个接受一个string参数的构造函数,创建一个新的WordQuery对象,然后将指向Query_base的智能指针绑定到派生类WordQuery身上。

        3.对于NotQuery,AndQuery,OrQuery这三个派生类,Query提供一个接受指向Query_base的智能指针shared_ptr的构造函数,用来初始化指向Query_base的智能指针p,这个构造函数是为了支持&、|、~运算符而设定。

        4.Query类中重写Query_base中的eval(),rep(),间接调用Query_base的派生类对象的eval()和rep()函数。

3.WordQuery类:Query_base的派生类,用于查找一个给定的单词

4.NotQuery类:Query_base的派生类,查询的结果是Query运算对象没有出现的句子集合

5.BinaryQuery类:Query_base派生出来的另外一个抽象基类,表示双目运算查询

6.AndQuery:BinaryQuery的派生类,两个单词同时出现的行的交集

7.OrQuery:BinaryQuery的派生类,两个单词出现的行的并集

完整代码:分为 TextQuery. h、Query_base.h和main.test文件

TextQuery.h

该代码基本已在Day14的文本查询中完成,这里增加了:

1.防止头文件包含宏指令。---不能少

2.QueryResult中多了三个函数:

       1. set<line_no>::iterator begin()---返回行号集合的首尾置迭代器

        2.set<line_no>::iterator end()---返回行号集合的末尾迭代器

        3.shared_ptr<vector<string>> &get_file()//获取句子容器vector的智能指针        

#ifndef __TEXTQUERY_H__
#define __TEXTQUERY_H__ //防止头文件重复包含,必须写
#include <iostream>
#include<fstream>
#include <sstream>
#include <iterator>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#include <memory>
#include <string>
using std::istringstream;
using std::set;
using std::pair;
using std::ifstream;
using std::ostream;
using std::string;
using std::vector;
using std::cout;
using std::endl;
using std::cerr;
using std::map;
using std::shared_ptr;
using std::cin;
class QueryResult;
class TextQuery
{
public:
    using line_no = vector<string>::size_type;//给vector<string>::size_type起别名
    //size_type:是个unsigned类型,其长度与机器匹配,ubuntu下,为unsigned long类型
    TextQuery(ifstream &);//构造函数,传入文件名
    QueryResult query(const string &)const; //查询,
private:
    shared_ptr<vector<string>> file;//输入文件
    map<string, shared_ptr<set<line_no>>> wm;//一个智能指针管理一个set
};
class QueryResult
{
	friend ostream& print(ostream &,const QueryResult &);//打印输出
public:
    using line_no = vector<string>::size_type;//给vector<string>::size_type起别名
    set<line_no>::iterator begin()
    {
        return lines->begin();//返回第一个行号的迭代器
    }

    set<line_no>::iterator end()
    {
        return lines->end();//最后一个行号的迭代器
    }

    shared_ptr<vector<string>> &get_file()
    {
        return file;//单词所对应句子的智能指针
    }
    
    QueryResult(string s, shared_ptr<set<line_no>> p,shared_ptr<vector<string>> f)
    :sought(s),lines(p),file(f) //有参构造函数,
    {
    }  

private:
    string sought;//用于查询单词
    shared_ptr<set<line_no>> lines;//保存,出现的行号
    shared_ptr<vector<string>> file;//输入文件
};
void parseText(string &text)//解析句子,大写换小写,去掉句子首尾空格
{
    for(int i=0;i<text.size();i++)
    {
        if(text[i]>='A&#
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给你。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值