C++ primer 15.9文本查询程序理解

这篇博客详细介绍了如何使用C++ Primer的知识设计和实现一个文本查询程序,包括单个单词查询、非查询、两个单词的并集和交集查询。程序通过类继承和智能指针管理来构建Query_base的继承体系,隐藏复杂性并提供统一的接口。文章还给出了不同查询类型的实现关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先准备一个.txt文件做查询使用。例如下(准备英文即可,中文暂不支持):
在这里插入图片描述
要实现的功能如下:
1、查询单个单词
2、查询单个单词的非
在这里插入图片描述
3、查询两个单词的并集
4、查询两个单词的交集
在这里插入图片描述
由题目观察可知,我们应该将几种不同的查询建模成相互独立的类,这些类共享一个公共基类。
这些类将只包含两个操作:
eval:接受一个TextQuery对象并返回一个QueryResult,eval函数使用给定的TextQuery对象查找与之匹配的行。
rep:返回基础查询的string表示形式,eval函数使用rep创建一个表示匹配结果的QueryResult,输出运算符使用rep打印查询表达式。

Query_base 继承体系设计如下:
在这里插入图片描述
在程序中我们还将定义一个Query的接口类,由它负责隐藏整个继承体系。
Query类将保存一个Query_base指针,该指针绑定到Query_base的派生类对象上。这样Query类与Query_base类提供的操作是相同的:eval用于求查询结果,rep用于生成查询的string结果,同时Query 也会定义一个重载的输出运算符用于显示查询。
设计类图如下:
在这里插入图片描述
github 地址:https://github.com/HSbear/TextSearch
实现代码:

#include <iostream>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <fstream>
#include <sstream>
#include <memory>
#include<algorithm>

using namespace std;
class QueryResult;

class TextQuery
{
   
   
public:
        using line_no = vector<string>::size_type;
		TextQuery(ifstream&);
        QueryResult query(const string&)const;
private:
        shared_ptr<vector<string>> file; //输入文件
        map<string,shared_ptr<set<line_no>>> wordmap;
};

class QueryResult {
   
   
    friend ostream &print(ostream &,const QueryResult &);
public:
    QueryResult(string s,
                shared_ptr<set<TextQuery::line_no>> p,
                shared_ptr<vector<string>> f)
                : sought(s)
                , lines(p)
                , file(f)
                {
   
   }
    set<TextQuery::line_no>::iterator begin() {
   
    return lines->begin(); }
	set<TextQuery::line_no>::iterator end() {
   
    return lines->end(); }
	shared_ptr<vector<string>> get_file() {
   
    return file; }
private:
    string sought;
    shared_ptr<set<TextQuery::line_no>> lines;
    shared_ptr<vector<string>> file;
};

TextQuery::TextQuery(ifstream &is)
: file(new vector<string>)
{
   
   
    string text;
    while(getline(is,text)){
   
   
        file->push_back(text);
        int n=file->size() - 1;
        istringstream line(text);
        string word;
        while(line >> word)
        {
   
   
            auto &lines = wordmap[word];
            if(!lines)
                lines.reset(new set<line_no>);
            lines->insert(n);
        }
    }
}

QueryResult TextQuery::query(const string& sought) const
{
   
   
    //如果未找到sought,则返回一个指向此set的指针
    static shared_ptr<set<
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值