C++ primer 第12章 12.3 使用标准库:文本查询程序

文章目录

  • 使用标准库:文本查询程序
    • 文本查询程序设计
      • 数据结构
      • 在类之间共享数据
      • 自己的文本查询程序
      • 书中的文本查询程序

使用标准库:文本查询程序

我们将实现一个简单的文本查询程序,作为标准库相关内容学习的总结。

我们的程序允许用户在一个给定文件中查询单词。查询结果是单词在文件中出现的次数及其所在行的列表。如果一个单词在一行中出现多次,此行只列出一次。行会按照升序输出。

文本查询程序设计

在这里插入图片描述

数据结构

我们定义一个保存输入文件的类,将这个类命名为TextQuery,它包含一个vector和一个map。vector用来保存输入文件的文本,map用来关联每个单词和它出现的行号的set。这个类将会有一个用来读取给定输入文件的构造函数和一个执行查询的操作。
在这里插入图片描述

在类之间共享数据

在这里插入图片描述

自己的文本查询程序

TextQuery类

#ifndef __TEXTQUERY__
#define __TEXTQUERY__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
#include<fstream>
#include<sstream>
#include"QueryResult.h"
using namespace std;class TextQuery {
public:TextQuery() {}TextQuery(ifstream &ifs);QueryResult query(string & s);
private:shared_ptr<vector<string>>strText;shared_ptr<map<string,set<int>>>strNum;
};TextQuery::TextQuery(ifstream &ifs) {string str;vector<string>vec;while (getline(ifs, str)) {vec.push_back(str);}strText = make_shared<vector<string>>(vec);map<string, set<int>>mp;int LineNum = 1;for (auto a : *strText) {istringstream vecStr(a);string tmp;while (vecStr >> tmp) {mp[tmp].insert(LineNum);}LineNum++;}strNum = make_shared<map<string, set<int>>>(mp);cout << "success1"<<endl;
}QueryResult TextQuery::query(string & s) {if (strNum->find(s) == strNum->cend()) {return QueryResult(s, 0, strText, strNum);}int num = (strNum->at(s)).size();cout << "num:"<<num << endl;return QueryResult(s,num, strText, strNum);
}#endif

QueryResult类

#ifndef __QUERYRESULT__
#define __QUERYRESULT__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
using namespace std;class QueryResult {
public:QueryResult() {}QueryResult(string&s,int num,shared_ptr<vector<string>>strText, shared_ptr<map<string, set<int>>>strNum):str(s),nums(num),strText(strText),strNum(strNum){}string getStr() { return str; }int getNums() { return nums; }shared_ptr<vector<string>> getStrText() { return strText; }shared_ptr<map<string, set<int>>>getStrNum() { return strNum; }
private:string str;int nums;shared_ptr<vector<string>>strText;shared_ptr<map<string, set<int>>>strNum;
};ostream & print(ostream &os, QueryResult &qr) {if (qr.getNums() == 0) {os << qr.getStr() << " occurs " << qr.getNums() << " time" << endl;return os;}os << qr.getStr() << " occurs " << qr.getNums() << (qr.getNums() > 1 ? "times" : "time") << endl;shared_ptr<map<string, set<int>>> mp = qr.getStrNum();shared_ptr<vector<string>>vec = qr.getStrText();set<int>st=mp->at(qr.getStr());for (auto n:st) {os << "(line" << n << ")" << vec->at(n-1) << endl;}return os;}#endif

测试程序:

void testTextQuery() {ifstream infile("test.txt");TextQuery tq(infile);while (true) {cout << "enter word to look for,or q tu quit:"<<endl;string s;if (!(cin >> s) || s == "q")break;print(cout, tq.query(s)) << endl;}
}

书中的文本查询程序

TextQuery类

#ifndef __TEXTQUERY__
#define __TEXTQUERY__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
#include<fstream>
#include<sstream>
#include"QueryResult.h"
using namespace std;class TextQuery {
public:using line_no = vector<string>::size_type;TextQuery() {}TextQuery(ifstream &ifs);QueryResult query(const string & s)const;
private:shared_ptr<vector<string>>strText;map<string, shared_ptr<set<line_no>>>strNum;
};TextQuery::TextQuery(ifstream &ifs):strText(new vector<string>) {string str;while (getline(ifs, str)) {strText->push_back(str);int n = strText->size() - 1;istringstream vecStr(str);string word;while (vecStr >> word) {auto &lines = strNum[word];//lines是一个shared_ptrif (!lines)//在我们第一次遇到这个单词时,此指针为空lines.reset(new set<line_no>);//分配一个新的setlines->insert(n);}}
}QueryResult TextQuery::query(const string & s)const {static shared_ptr<set<line_no>>nodata(new set<line_no>);if (strNum.find(s) == strNum.cend()) {return QueryResult(s,strText, nodata);}elsereturn QueryResult(s,strText, strNum.find(s)->second);
}#endif

QueryResult类

#ifndef __QUERYRESULT__
#define __QUERYRESULT__#include<string>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<memory>
using namespace std;class QueryResult {friend ostream& print(ostream &os, const QueryResult &qr);
public:using line_no = vector<string>::size_type;QueryResult() {}QueryResult(const string&s,shared_ptr<vector<string>>strText, shared_ptr<set<line_no>>strNum):str(s),strText(strText),strNum(strNum){}private:string str;shared_ptr<vector<string>>strText;shared_ptr<set<line_no>>strNum;
};ostream & print(ostream &os, const QueryResult &qr) {os << qr.str << " occurs " << qr.strNum->size()<< (qr.strNum->size() > 1 ? " times" : " time") << endl;for (auto n:*qr.strNum) {os << "\t(line" << n+1 << ")" << qr.strText->at(n) << endl;}return os;}#endif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/446552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言二维数组 int arr[2][3]

基础使用 先遍历行再遍历列 #include<stdio.h> //二维数组的基本使用 int main() {//二维数组的初始化int arr1[2][2]{{2,2},{0,0}};int arr2[2][3]{2,2,2,8,8,8};int arr3[6][9];int i,j;for(i0;i<6;i){for(j0;j<9;j){arr3[i][j]1;}}arr3[2][5]0;//打印printf(&…

牛客网C++面经 类和数据抽象

请你来说一下C中struct和class的区别 在C中&#xff0c;可以用struct和class定义类&#xff0c;都可以继承。区别在于&#xff1a;structural的默认继承权限和默认访问权限是public&#xff0c;而class的默认继承权限和默认访问权限是private。另外&#xff0c;class还可以定义…

C++ primer 第13章 拷贝控制

文章目录前言拷贝、赋值与销毁拷贝构造函数合成拷贝构造函数拷贝初始化和直接初始化拷贝初始化的发生&#xff1a;参数和返回值拷贝初始化的限制拷贝赋值运算符重载赋值运算符合成拷贝赋值运算符析构函数析构函数完成的工作什么时候会调用析构函数合成析构函数代码片段调用几次…

C语言 指针自增自减加减运算 p++ p+i

介绍 自增自减代码 #include<stdio.h> #include<string.h> //指针自增--short void increase(short *arr,int len) {int i;arr&arr[0];for(i0;i<len;i){printf("arr[%d]%d,address%p\n",i,*arr,arr);arr;} }//指针自减--char void decrease(char…

C++ 编译与底层

原文链接 编译与底层请你来说一下一个C源文件从文本到可执行文件经历的过程&#xff1f; 对于C源文件&#xff0c;从文本到可执行文件一般需要四个过程&#xff1a;预处理阶段&#xff1a;对源代码文件中文件包含关系&#xff08;头文件&#xff09;、预编译语句&#xff08;…

C语言 指针数组-字符指针数组整型指针数组 char*s[3] int*a[5] 数组指针int(*p)[4]

基本介绍 1.指针数组:由n个指向整型元素的指针而组成,里面存放指针 Int *ptr[3]; 2.地址: ptr[i]:元素地址 &ptr[i]:指针地址 图示 代码: 内存布局: 代码 #include<stdio.h> #include<string.h> //指针数组--int void pointer(int *arr,int len) {int …

uninitialized_copy测试代码示例

原测试代码如下&#xff1a; int main() {vector<int>v1{1,3,5,7,9,2,4,6,8};allocator<int>alloc;auto data alloc.allocate(9);uninitialized_copy(v1.begin(),v1.end(), data);auto end data 9;while(data!end) {cout << *data <<" "…

C语言的地址 内存

取地址在CPU的寄存器产生&#xff0c;不占据内存地址由计算器总线&#xff0c;地址作为常量不消耗内存指针 存储不同的地址&#xff0c;间接赋值空类型指针 void* 类型指针 不可以取数据 或者修改数据 需要进行强制类型转换int num 10;void *p &num;std::cout << …

C语言 多重指针--整型字符字符串 int**pp

介绍 多重指针:一个指针指向另一个指针 离值越近的指针级别越大:一级 内存布局 代码 图示: 多重指针–整型 #include<stdio.h> #include<string.h> //多重指针--整型//二级指针 void two() {printf("二级指针:\n");int a896;int *p&a,**pp&…

C++ primer 第13章 拷贝控制

文章目录前言拷贝、赋值与销毁拷贝构造函数合成拷贝构造函数拷贝初始化和直接初始化拷贝初始化的发生&#xff1a;参数和返回值拷贝初始化的限制拷贝赋值运算符重载赋值运算符合成拷贝赋值运算符析构函数析构函数完成的工作什么时候会调用析构函数合成析构函数代码片段调用几次…

牛客网C++面经 C++11

请问C11有哪些新特性&#xff1f; auto关键字&#xff1a;编译器可以根据初始值自动推导出类型。但是不能用于函数传参以及数组类型的推导nullptr关键字&#xff1a;nullptr是一种特殊类型的字面值&#xff0c;它可以被转换成任意其它的指针类型&#xff1b;而NULL一般被宏定义…

C语言 返回指针的函数--指针函数 int* max(int a)

定义 strlong示例代码 代码1: #include<stdio.h> #include<string.h> //返回指针的函数//比较两个字符串,返回更长的字符串 char *strlong(char* a,char* b) {char *p1&a[0];char *p2&b[0];while(true){if(*p1\0){return b;}else if(*p2\0){return a;}p1…

第2、3讲 图像的存储格式

本图像处理系列笔记是基于B站杨淑莹老师的课程进行学习整理的。 文章目录黑白图像8位灰度索引图像8位伪彩色索引图像24位真彩色图像图像文件格式BMP文件存储格式BMP文件头位图信息头颜色表位图信息——BITMAPINFO结构BMP位图文件汇总按照颜色深度分类&#xff0c;常用图像文件&…

Ubuntu18.04.4 环境下对属性加密算法CP-ABE环境搭建

注意事项 cpabe依赖pbc&#xff0c;pbc依赖gmp&#xff0c;gmp依赖M4、bison、flex如果权限不够 &#xff0c;命令的前面加上sudo &#xff0c;不要直接使用root用户进行操作&#xff0c;其带来的隐患有很多 第一步 配置简单的环境 简单环境 包括gcc、g、make、cmake、openss…

C语言 函数指针 int(*ptr)(int,int)

基本介绍 函数指针:指向函数的指针 与数组类似 定义 Int(*pmax)(int ,int)max; Int(*pmax)(int x,int y)max;//形参名称不重要 函数返回类型(*指针)(形参类型)函数名称; 具体案例 代码: *pmax取到函数本身 调用函数指针方式: (*pmax)(x,y); pmax(x,y);//与java中调用函数一…

C++ primer 第14章 操作重载与类型转换

文章目录基本概念直接调用一个重载的运算符函数某些运算符不应该被重载使用与内置类型一致的含义选择作为成员或者非成员输入和输出运算符重载输出运算符<<输出运算符尽量减少格式化操作输入输出运算符必须是非成员函数重载输入运算符>>算术和关系运算符相等运算符…

C语言 回调函数 produce(arr,len,getRand)

基本介绍 回调函数:形参中包含另一个函数的函数指针 用函数指针接收另一个函数 案例 代码解析 具体代码 #include<stdio.h> #include<stdlib.h> //回调函数--//函数原型 int getRand(); int *produce(int*arr,int len,int(*get)()); int main() {int arr[10…

从零开始配置服务器密码机的开发环境

开发环境环境配置安装gcc编译器安装g编译器安装make安装cmake安装ssh安装git和配置安装大文件管理工具git-lfs安装数据库sqlite3安装数据库sqlite_orm文件安装Openssl安装Tcl和Tk安装tcl-expect-dev安装boost安装clang-format安装Clion注意事项安装automake和libudev-dev环境配…

C语言 动态内存分配机制(堆区) int*p=malloc(5*sizeof(4))

C程序内存分配图 栈区:局部变量 堆区:动态分配的数据 静态存储区/全局区:全局变量,静态数据 代码区:代码,指令 内存分配说明 内存动态分配的相关函数 堆区: #inlcude<stdlib.h> Malloc(size);//分配长度为size个字节的连续空间 Calloc(n,size);//分配size个长度为n…

C++ primer 第15章 面向对象程序设计

文章目录前言OOP&#xff1a;概述继承动态绑定定义基类和派生类定义基类成员函数与继承访问控制与继承定义派生类派生类中的虚函数派生类对象及派生类向基类的类型转换派生类构造函数派生类使用基类的成员继承与静态成员派生类的声明被用作基类的类防止继承的发生类型转换与继承…