功能:

本程序允许用户在一个给定的文件中查询单词。查询结果是单词在文件中出现的次数及其所在行的列表。如果一个单词在一行中出现多次,此行只列出一次。行会按照升序输出,即第7行会在第9行之前显示。

思路:

  • 使用vector来保存整个输入文件的一份拷贝。输入文件中每一行保存为vector中的元素。当需要打印一行时,可以用行号作为下标来提取行文本。
  • 使用istringstream来将每行分解为单词。
  • 使用set来保存每个单词输入文本中出现的行号(有序的set)
  • 使用map来将每个单词与它出现的行号set关联起来,这样就可以快速提取任意单词的set。

源码:

TextQuery.h文件

//
// Created by liangyh on 7/9/2017.
//#ifndef SECOND_TEXTQUERY_H
#define SECOND_TEXTQUERY_H#include <vector>
#include <map>
#include <set>
#include "QueryResult.h"using namespace std;class TextQuery {public:using line_no = vector<string>::size_type;TextQuery(ifstream &inFile);QueryResult query(string &sought);private:shared_ptr<vector<string>> file;map<string, shared_ptr<set<line_no>>> wordMap;
};#endif //SECOND_TEXTQUERY_H

TextQuery.cpp文件

#include <fstream>
#include <sstream>
#include "TextQuery.h"//构造:file文件对象和wordMap对象。
TextQuery::TextQuery(ifstream &inFile) :file(new vector<string>) {string line;while (getline(inFile, line)) {file->push_back(line);istringstream words(line);string word;while (words >> word) {shared_ptr<set<line_no >> &lines = wordMap[word];if (!lines) {lines.reset(new set<line_no >);//wordMap[word] = lines;//开始的时候wordMap中的value值是NULL的。}lines -> insert(file->size() - 1);}}
}QueryResult TextQuery::query(string &sought) {static shared_ptr<set<line_no >> noData(new set<line_no >);auto pair = wordMap.find(sought);if (pair == wordMap.end()) {//not foundreturn QueryResult(sought, noData, file);}else {return QueryResult(sought, pair->second, file);}
}

QueryResult.h文件

//
// Created by liangyh on 7/9/2017.
//#ifndef SECOND_QUERYRESULT_H
#define SECOND_QUERYRESULT_H#include <vector>
#include <set>
#include <map>
#include <memory>using namespace std;class QueryResult {
public:using line_no = vector<string>::size_type;QueryResult(string sought, shared_ptr<set<line_no >> numSet, shared_ptr<vector<string>> file);void print();private:string sought;shared_ptr<vector<string>> file;shared_ptr<set<line_no>> numSet;};
#endif //SECOND_QUERYRESULT_H

QueryResult.cpp文件

//
// Created by liangyh on 7/9/2017.
//#include <iostream>
#include <string>
#include "QueryResult.h"QueryResult::QueryResult(string sought,shared_ptr<set<line_no >> numSet,shared_ptr<vector<string>> file) :sought(sought), numSet(numSet), file(file) {}void QueryResult::print() {cout << "sought word is: " << sought << endl;if (numSet->size() > 0) {for (auto num : *numSet) {cout << *(file->begin() + num) << endl;cout << "-----" << endl;}}else {cout << sought << ": ------------0------------" << endl;}
}

main函数

#include <iostream>
#include <fstream>
#include <string>#include "TextQuery.h"
#include "QueryResult.h"using namespace std;int main() {string filePath = "C:\\Users\\liangyh\\Desktop\\TEMP\\query.txt";ifstream file(filePath.c_str());if (file.is_open()) {TextQuery textQuery(file);string soughtWord = "is";QueryResult result = textQuery.query(soughtWord);result.print();}system("pause");return 0;
}

思考:指针的引用

下面是构造函数的代码

//构造:file文件对象和wordMap对象。
TextQuery::TextQuery(ifstream &inFile) :file(new vector<string>) {string line;while (getline(inFile, line)) {file->push_back(line);istringstream words(line);string word;while (words >> word) {shared_ptr<set<line_no >> &lines = wordMap[word];if (!lines) {lines.reset(new set<line_no >);//wordMap[word] = lines;//开始的时候wordMap中的value值是NULL的。}lines -> insert(file->size() - 1);}}
}

该构造方法中使用到了指针的引用,该行代码为:

shared_ptr<set<line_no >> &lines = wordMap[word];

lines是一个指针,修改lines的内容就会修改它所指向的内容;同时,lines又是引用,因此,(*lines)就代表了lines所指向的内容本身:一开始的时候,wordMap[word]是null的,所以(*line)也是null的,当执行完下面两行代码之后,*lines就不再为null了。又因为lines是wordMap[word]的引用,因此wordMap[word]也不为null了。

lines.reset(new set<line_no >);
lines -> insert(file->size() - 1);

如果不使用指针的引用,需要怎么修改呢?先贴出代码

shared_ptr<set<line_no >> lines = wordMap[word];
if (!lines) {lines.reset(new set<line_no >);wordMap[word] = lines;
}
lines -> insert(file->size() - 1);

开始的时候wordMap[word]是null的,在初始化lines变量的时候并不能让lines指向一个有效的地址,也就是开始的时候lines是空指针。它跟lines没有关联,即使执行了lines.reset(new set<line_no >);,wordMap[word]还是为null。因此,需要我们把他们关联起来,即wordMap[word] = lines;
所有,把代码改成如下所示的样子也是可以的。

while (words >> word) {shared_ptr<set<line_no>> tmpLines(new set<line_no>);wordMap.insert(pair<string, shared_ptr<set<line_no>>>(word, tmpLines));shared_ptr<set<line_no >> lines = wordMap[word];if (!lines) {lines.reset(new set<line_no >);//wordMap[word] = lines;}lines->insert(file->size() - 1);
}

对于指针的引用,有一个demo,p是指针的引用,因此,p代表了temp变量,*p改变的时候,temp也会改变。

void test() {int a = 1;int *temp = &a;int *&p = temp;cout << "*p = " << *p << endl;cout << "temp = " << *temp << endl;*p = 5;cout << "*p = " << *p << endl;cout << "temp = " << *temp << endl;int b = 2;p = &b;cout << "*p = " << *p << endl;cout << "temp = " << *temp << endl;
}

执行的结果是:

*p = 1
temp = 1
*p = 5
temp = 5
*p = 2
temp = 2
Press any key to continue . . .

结束!

C++ demo:文本搜索以及'指针的引用'的思考相关推荐

  1. C++(9)--裸指针、智能指针、引用

    指针 1.裸指针的基本概念 1.1 裸指针的声明*/初始化& 1.2 操作裸指针--间接运算符* 1.3 裸指针使用 demo--指向一个简单变量 1.4 空指针--nullptr 1.5 特 ...

  2. Linux学习命令汇总三——Linux用户组管理,文件权限管理,文本搜索命令grep及正则表达式...

    本章Blog相关Linux知识点 解析:在数据库按搜索码查找相对应的条目,并找与之对应额外的其他数据库的过程:名称解析:UID ,组名解析:GID 数据库:文本文件,sql数据库,ldap数据库,用户 ...

  3. 数据库9:联结表 高级联结 组合查询 全文本搜索

    第十五章联结表 Sql最强大的功能之一就是能在数据检索查询的执行中联结(join)表.联结是利用sql的select能执行的最重要的操作,能很好的理解联结及其语法是学习sql的一个极为重要的组成部分. ...

  4. c++中的引用和python中的引用_对比 C++ 和 Python,谈谈指针与引用

    作者 | 樱雨楼 引言 指针(Pointer)是 C.C++ 以及 Java.Go 等语言的一个非常核心且重要的概念,而引用(Reference)是在指针的基础上构建出的一个同样重要的概念. 指针对于 ...

  5. C++中的指针与引用

    写在前面 指针和引用形式上很好区别,但是他们似乎有相同的功能,都能够直接引用对象,对其进行直接的操作.但是什么时候使用指针?什么时候使用引用呢?这两者很容易混淆,在此我详细介绍一下指针和引用,力争将最 ...

  6. MySQL(十)操纵表及全文本搜索

    一.创建表 MySQL不仅用于表数据操作,还可以用来执行数据库和表的所有操作,包括表本身的创建和处理. 创建表一般有如下两种方式: ①使用具有交互式创建和管理表的工具: ②直接使用MySQL语句操纵表 ...

  7. Linux(debian7)操作基础(十四)之文本搜索命令grep使用方法

    一.简介 grep(global search regular RE ) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它只能使用基本的正则 ...

  8. c6011取消对null指针的引用_COM编程攻略(二十二 IDL中的枚举,指针,数组)

    上一篇: Froser:COM编程攻略(二十一 异步)​zhuanlan.zhihu.com 本篇主要讲idl的一些语法特性. idl的语法和C语言非常类似,但是它扩展了一些特性,这些特性用于兼容其它 ...

  9. sql server的搜索_在SQL Server中进行全文本搜索

    sql server的搜索 介绍 (Introduction) In most cases, we will use clustered and non-clustered indexes to he ...

最新文章

  1. Nat. Biotechnol.| 基于生物活性建模识别抗SARS-CoV-2药物
  2. java bio_Java BIO及实现
  3. python怎么读文件内容-Python 文件内容读取
  4. 产品需求文档的10步
  5. java动态添加view
  6. 实时数据交换平台 - BottledWater-pg with confluent
  7. ERP平台的自动化测试技术实践
  8. Apache Camel 3只有2个月的路程
  9. mvc 怎么把后台拼接好的div写到前台_MVC 从后台页面 取前台页面传递过来的值的几种取法...
  10. 【转】架构师Jack专访:全面认识软件测试架构师
  11. python常用代码入门-入门十大Python机器学习算法(附代码)
  12. 解决PID 4、NT Kernal占用80、445等端口
  13. Linux-socket使用
  14. ArrayList类的使用方法
  15. 怎么完全卸载赛门铁克_Symantec卸载方法,赛门铁克卸载
  16. 计算机命令关闭445端口,怎么关闭445端口-关闭windows端口的批处理命令
  17. 李健清华计算机专业,计算机DeepWeb数据库的分类研究李健
  18. 数据治理-数据质量-数据质量参考架构
  19. 404错误是什么意思?为什么是404?
  20. android 应用变量,真正免root的应用变量详细使用教程

热门文章

  1. 计算机专业英语文章翻译,计算机专业英语英汉双语文章翻译
  2. linux+传输文件时卡住,linux - rsync 同步文件时卡住不动
  3. php带帽接口_利用php自包含特性上传webshell
  4. 关于Mybaits,我总结了10种通用的写法
  5. 【LC3开源峰会网络技术系列之三】基于JStorm的网络分析平台
  6. js中push和pop的用法
  7. The method createCall() from the type Service refers to the missing type Call
  8. 优化函数式编程:向 PHP 移植 Clojure 函数
  9. shell下 使用心得
  10. lisp提取长方形坐标_求修改lisp程序,如何提取CAD中多个点的坐标,(本人想提取UCS坐标系)另外只需要提取X,Y值,不要Z...