C++ demo:文本搜索以及'指针的引用'的思考
功能:
本程序允许用户在一个给定的文件中查询单词。查询结果是单词在文件中出现的次数及其所在行的列表。如果一个单词在一行中出现多次,此行只列出一次。行会按照升序输出,即第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:文本搜索以及'指针的引用'的思考相关推荐
- C++(9)--裸指针、智能指针、引用
指针 1.裸指针的基本概念 1.1 裸指针的声明*/初始化& 1.2 操作裸指针--间接运算符* 1.3 裸指针使用 demo--指向一个简单变量 1.4 空指针--nullptr 1.5 特 ...
- Linux学习命令汇总三——Linux用户组管理,文件权限管理,文本搜索命令grep及正则表达式...
本章Blog相关Linux知识点 解析:在数据库按搜索码查找相对应的条目,并找与之对应额外的其他数据库的过程:名称解析:UID ,组名解析:GID 数据库:文本文件,sql数据库,ldap数据库,用户 ...
- 数据库9:联结表 高级联结 组合查询 全文本搜索
第十五章联结表 Sql最强大的功能之一就是能在数据检索查询的执行中联结(join)表.联结是利用sql的select能执行的最重要的操作,能很好的理解联结及其语法是学习sql的一个极为重要的组成部分. ...
- c++中的引用和python中的引用_对比 C++ 和 Python,谈谈指针与引用
作者 | 樱雨楼 引言 指针(Pointer)是 C.C++ 以及 Java.Go 等语言的一个非常核心且重要的概念,而引用(Reference)是在指针的基础上构建出的一个同样重要的概念. 指针对于 ...
- C++中的指针与引用
写在前面 指针和引用形式上很好区别,但是他们似乎有相同的功能,都能够直接引用对象,对其进行直接的操作.但是什么时候使用指针?什么时候使用引用呢?这两者很容易混淆,在此我详细介绍一下指针和引用,力争将最 ...
- MySQL(十)操纵表及全文本搜索
一.创建表 MySQL不仅用于表数据操作,还可以用来执行数据库和表的所有操作,包括表本身的创建和处理. 创建表一般有如下两种方式: ①使用具有交互式创建和管理表的工具: ②直接使用MySQL语句操纵表 ...
- Linux(debian7)操作基础(十四)之文本搜索命令grep使用方法
一.简介 grep(global search regular RE ) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它只能使用基本的正则 ...
- c6011取消对null指针的引用_COM编程攻略(二十二 IDL中的枚举,指针,数组)
上一篇: Froser:COM编程攻略(二十一 异步)zhuanlan.zhihu.com 本篇主要讲idl的一些语法特性. idl的语法和C语言非常类似,但是它扩展了一些特性,这些特性用于兼容其它 ...
- sql server的搜索_在SQL Server中进行全文本搜索
sql server的搜索 介绍 (Introduction) In most cases, we will use clustered and non-clustered indexes to he ...
最新文章
- Nat. Biotechnol.| 基于生物活性建模识别抗SARS-CoV-2药物
- java bio_Java BIO及实现
- python怎么读文件内容-Python 文件内容读取
- 产品需求文档的10步
- java动态添加view
- 实时数据交换平台 - BottledWater-pg with confluent
- ERP平台的自动化测试技术实践
- Apache Camel 3只有2个月的路程
- mvc 怎么把后台拼接好的div写到前台_MVC 从后台页面 取前台页面传递过来的值的几种取法...
- 【转】架构师Jack专访:全面认识软件测试架构师
- python常用代码入门-入门十大Python机器学习算法(附代码)
- 解决PID 4、NT Kernal占用80、445等端口
- Linux-socket使用
- ArrayList类的使用方法
- 怎么完全卸载赛门铁克_Symantec卸载方法,赛门铁克卸载
- 计算机命令关闭445端口,怎么关闭445端口-关闭windows端口的批处理命令
- 李健清华计算机专业,计算机DeepWeb数据库的分类研究李健
- 数据治理-数据质量-数据质量参考架构
- 404错误是什么意思?为什么是404?
- android 应用变量,真正免root的应用变量详细使用教程
热门文章
- 计算机专业英语文章翻译,计算机专业英语英汉双语文章翻译
- linux+传输文件时卡住,linux - rsync 同步文件时卡住不动
- php带帽接口_利用php自包含特性上传webshell
- 关于Mybaits,我总结了10种通用的写法
- 【LC3开源峰会网络技术系列之三】基于JStorm的网络分析平台
- js中push和pop的用法
- The method createCall() from the type Service refers to the missing type Call
- 优化函数式编程:向 PHP 移植 Clojure 函数
- shell下 使用心得
- lisp提取长方形坐标_求修改lisp程序,如何提取CAD中多个点的坐标,(本人想提取UCS坐标系)另外只需要提取X,Y值,不要Z...