TextQuery程序

我写的第一个版本

返回的是map<size_t, string>这个数据量很大,效率低下。

TextQuery.h

#inlucde<vector>
#include<map>
#include<set>
#include<iterator>
#include<fstream>
#include<iostream>
#include<sstream> using namespace std; #ifndef TEXTQUERY__H
#define TEXTQUERY__H class TextQuery {
public:
TextQuery() = default;
TextQuery(ifstream &is);
map<size_t, string> query(const string &str); private:
vector<string> text;
map<string, set<size_t>> lut;
}; #endif

TextQuery.cpp

include "TextQuery.h"

TextQuery::TextQuery(ifstream &is) {
string line;
istringstream iss;
string word;
size_t line_cnt = 0; while(getline(is, line)) {
iss.clear();
iss.str(line);
text.push_back(line);
while(iss>>word) {
if(lut.fine(word) != lut.end()) {
lut[word].insert(line_cnt);
} else {
lut[owrd] = set<size_t>{line_cnt};
}
}
++line_cnt;
}
} map<size_t, string> TextQuery::query(const string &str) {
map<size_t, string> sh;
auto p = lut.find(str);
if((p != lut.end()) {
for(auto iter = p->second.begin(); iter != p->second.end(); ++iter) {
sh[*iter] = text[*text];
}
} return sh;
}

这里用到了set<size_t>{line_cnt}来构造一个匿名的对象,赋值给map。但是不能用set<size_t> (line_cnt),因为set没有有参数的构造函数,有参数的也是拷贝的那种。

书上的版本

TextQuery.h

#pragma once
#include<vector>
#include<string>
#include<map>
#include<set>
#include<memory>
#include<fstream>
#include<sstream>
#include<iostream>
using namespace std; class QueryResult;
class TextQuery {
public:
TextQuery(ifstream &s);
QueryResult query(const string &str) const; private:
shared_ptr<vector<string>> text;
map < string, shared_ptr<set<size_t>>> lut;
}; class QueryResult {
public:
QueryResult(const string &str, shared_ptr<vector<string>> ptr, shared_ptr<set<size_t>> ln):sh(str), contents(ptr), lines(ln) {} shared_ptr<vector<string>> contents;
shared_ptr<set<size_t>> lines;
string sh;
}; void print(ostream &os, const QueryResult &qr);

TextQuery.cpp

#include "TextQuery.h"

TextQuery::TextQuery(ifstream &is) : text(make_shared<vector<string>>()) {
string line;
istringstream iss;
string word; while (getline(is, line)) {
iss.clear();
iss.str(line);
text->push_back(line);
//cout << line << endl;
while (iss >> word) {
//cout << word << endl;
auto &lines = lut[word];
if (!lines) {
lines.reset(new set<size_t>{ text->size() - 1 });
          // lines = make_shared<set<size_t>>();
         // lines->insert(text-size() -1);
} else {
lines->insert(text->size() - 1);
}
}
}
} QueryResult TextQuery::query(const string &str) const{
static shared_ptr<set<size_t>> st_ptr(new set<size_t>);
auto loc = lut.find(str);
if(loc != lut.end())
return QueryResult(str, text, loc->second);
else
return QueryResult(str, text, st_ptr); } void print(ostream &os, const QueryResult &pr) {
os << pr.sh << " occurs " << pr.lines->size() << " times"<<endl;
for (auto iter = pr.lines->begin(); iter != pr.lines->end(); ++iter) {
os << "(line " << *iter + 1 << ") " << (*pr.contents)[*iter] << endl;
}
}

测试代码

#include<iostream>
#include<fstream>
#include"TextQuery.h"
using namespace std; int main() {
ifstream is("TextQuery.cpp");
TextQuery tq(is); QueryResult qr = tq.query("QueryResult");
print(cout, qr); return 1;
}

这个代码相比我写的代码的优点

  1. 使用指针返回查找的数据,返回的数据量比较小,没有大量拷贝。
  2. 为了使用指针使用了shared_ptr
  3. 在判断map中lut[word]这个数据是否存在是巧妙的使用了map在没有word对应键的元素的时候会插入这个键,值使用值初始化,shared_ptr值初始化就是nullptr,根据是否为nullptr来确定是否需要分配set的空间。

c++ TextQuery程序的更多相关文章

  1. tuple类型的单词查询例子

    17.3 重写前面的TextQuery程序,使用tuple代替QueryResult类. TextQuery.h #ifndef TEXTQUERY_H #define TEXTQUERY_H #in ...

  2. C++关联容器综合应用:TextQuery小程序

    本文介绍C++关联容器综合应用:TextQuery小程序(源自C++ Primer). 关于关联容器的概念及介绍,请参考园子里这篇博文:http://www.cnblogs.com/cy568sear ...

  3. Chapter12&Chapter13:程序实例

    文本查询程序 要求:程序允许用户在一个给定文件中查询单词.查询结果是单词在文件中出现的次数及所在行的列表.如果一个单词在一行中出现多次,此行只列出一次. 对要求的分析: 1.读入文件,必须记住单词出现 ...

  4. c++ primer( 文本查询程序)

    读取用户指定的任意文本文件,然后允许用户从该文件查找单词,查询的结果是该单词出现的次数,并列出每次出现所在的行,如果某单词在同一行中多次出现,程序将只显示改行的一次.行号按升序显示(int main( ...

  5. C++ Primer第四版 15.9 再谈文本查询 程序实现

    编程过程中发现书本中的示例程序并不完全,某些地方存在错误,现已改正并添加少许注释.. 1 #include<iostream> 2 #include<fstream> #inc ...

  6. C++ Primer 学习笔记_38_STL实践与分析(12)--集成的应用程序容器:文本查询程序

    STL实践与分析 --容器的综合应用:文本查询程序 引言: 本章中最重点的实例.由于不须要用到multiset与multimap的内容.于是将这一小节提到了前面.通过这个实例程序,大师分析问题的智慧, ...

  7. C++ 容器的综合应用的一个简单实例——文本查询程序

    C++ 容器的综合应用的一个简单实例——文本查询程序 [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例.通过实现一个简单的文本查 ...

  8. 《C++ Primer》 chapter 15 TextQuery

    <C++ Primer>中第15章为了讲解面向对象编程,举了一个例子:设计一个小程序,能够处理查询给定word在文件中所在行的任务,并且能够处理“非”查询,“或”查询,“与”查询.例如执行 ...

  9. C++ Primer 学习笔记_91_用于大型程序的工具 --命名空间

    用于大型程序的工具 --命名空间 引言: 在一个给定作用域中定义的每一个名字在该作用域中必须是唯一的,对庞大.复杂的应用程序而言,这个要求可能难以满足.这样的应用程序的全局作用域中一般有很多名字定义. ...

随机推荐

  1. R语言基本数据对象之向量的主要运算

    在R语言里操作和接触的所有东西都称作对象(object).对象有很多种类 可以包含各种类型的数据.R 语言里所有的东西都被称为对象,R语言中常见的数据类型有几下几种,分别是字符型 (character ...

  2. Jmeter创建一个http请求

    1.点击'Test Plan'为测试计划命名为"创建用户接口" 2.新建一个[线程组],在[创建用户接口]处点击右键,选择[添加]-->[Threads(Users)]--& ...

  3. 【Java】Eclipse常用快捷键

    Eclipse常用快捷键 * 1.补全代码的声明:alt + / * 2.快速修复: ctrl + 1 * 3.批量导包:ctrl + shift + o * 4.使用单行注释:ctrl + / * ...

  4. 自旋锁-JUC系列

    公众号原文:自旋锁-JUC系列 前言 2022!这个年份现在看起来都觉得有那么些恍惚的未来感,然而现在已在脚下. 无边落木萧萧下, 不尽长江滚滚来! 人生如白驹过隙! 本来计划最近把AQS源码分析做了 ...

  5. 单片机main函数退出后发生什么——以stm32为例

    STM32:main函数退出后发生什么? 我们都在说单片机要运行在无限循环里,不能退出,可退出之后会发生什么? 讨论STM32启动过程的文章数不胜数,可main函数结束之后会发生什么却少有讨论. 几日 ...

  6. prometheus基本概念(思维导图)

    参考文章: prometheus词汇表 prometheus的summary和histogram指标的简单理解

  7. cv::copyMakeBorder()中用0值对齐矩阵,方便后续加速傅里叶变换

    int M = cv::getOptimalDFTSize(mul_result.rows); // 获得最佳DFT尺寸,为2的次方 int N = cv::getOptimalDFTSize(mul ...

  8. lagou数据爬取

    1. 使用的工具 selenium+xpath+ 手动输入登录 2. 实现的功能: 1.手动登录后,按终端提示,就能下载所需要的内容 import requests import json impor ...

  9. SpringCloud整合Hystrix

    1.Hystrix简介 Hystrix是由Nefflix开源的一个延迟和容错库,用于隔离访问远程系统.服务或第三方库,防止级联失败,从而提升系统的可用性.容错性与局部应用的弹性,是一个实现了超时机制和 ...

  10. Java的代理机制

    Java的代理机制 使用代理 Proxzy 可以在运行时创建一组给定接口的新类,这种功能只有在编译时无法确定需要实现哪种接口时才需要使用. 1. 使用代理的时机 假如有一个表示接口的 Class 对象 ...