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. vue3.0+vite+ts项目搭建--vite.config.ts配置(三)

    vite.config.ts配置 配置路径处理模块 安装ts的类型声明文件 yarn add @types/node -D 通过配置alias来定义路径的别名 resolve: { alias: { ...

  2. Kubernetes最佳实践之腾讯云TKE 集群组建

    作者陈鹏,腾讯工程师,负责腾讯云 TKE 的售中.售后的技术支持,根据客户需求输出合理技术方案与最佳实践,为客户业务保驾护航.使用 TKE 来组建 Kubernetes 集群时,会面对各种配置选项,本 ...

  3. HarmonyOS新能力让数据多端协同更便捷,数据跨端迁移更高效!

    作者:yijian,终端OS分布式文件系统专家:gongashi,终端OS分布式数据管理专家 HarmonyOS作为分布式操作系统,其分布式数据管理能力非常重要.我们也一直围绕持续为开发者带来全局&q ...

  4. phpAdmin写webshell的方法

    一.常规导入shell的操作    创建数据表导出shell    CREATE TABLE `mysql`.`shadow9` (`content` TEXT NOT NULL );    INSE ...

  5. IDEA导入Web项目配置Tomcat启动

    1.导入项目 2.配置project 3.导入项目模块 配置Models 4.配置Libraries 5. 6. 7.配置tomcat

  6. 解决excel两表之间数据关联关系,知道这几招就够了

    用过SAP的凭证批量录入模板(Excel文件)的都知道,一个凭证由[抬头]和多个[行项目]组成,这是一个关于excel两表信息关联的典型场景. 这里头蕴藏着一个麻烦:当我们需要一次性录入多个凭证时,如 ...

  7. 【Java】toString

    toString 当我们输出一个对象的引用时,实际上就是调用当前对象的toString() Object类中toString()的定义: public String toString() { retu ...

  8. uboot无法通过nfs加载ubuntu18.04中的文件(转)

    问题描述: i.mx6ull开发板,采用alientek官方维护的uboot,使用ubuntu18.04 lts作为nfs server,导致开发板uboot上nfs命令无法加载网络文件系统. 解决: ...

  9. Three.js之绘制物体的边框及修改lineWidth

    本博文主要记录如何使用three.js绘制物体的边框及修改其lineWidth.three.js是个技术点比较多,查询资料又比较少的框架,单单就这个修改lineWidth就是一个坑.先放一个动态的效果 ...

  10. HttpRunner3的变量是如何传递的

    HttpRunner3的变量可以在测试类的用例配置中通过variables添加,也可以在测试步骤中使用extract().with_jmespath()提取出来放到变量x,再用$x传递给下一个接口使用 ...