c++学习笔记:文本查询程序
来源:互联网 发布:考研有多难放弃知乎 编辑:程序博客网 时间:2024/06/07 03:22
文本查询程序:
在给定的文件中查询一个单词出现的次数及其所在行的列表,如果单词在一行中出现多次,那这一行的文本只列出一次
1)使用一个vector<string>来保存文件的一份拷贝,文件的每一行作为vector对象的一个元素。当要打印一行时,使用下标来提取一行的文本。
2)使用istringstream来把每一行分解成一个个单词
3)使用set来保存每个单词在文本中出现的行号,保证行号只出现一次
4)使用map来将每个单词和它出现的行号set关联在一起
一。建立映射关系
1)BuildMap函数接受两个参数,一个是文件输入流,一个是vector对象,两个都是传引用。因为流不能拷贝,所以只能要传引用。而vector传引用是直接存入在主函数中定义的vector对象,这个对象保存的是文件的一份副本。
2)函数先用getline函数循环读取文件的每一行,然后存入传进来的vector对象当中,vector对象的size作为行号
3)然后使用istringstream将每一行文本分解成一个个单词,每个单词作为map对象的关键字。然后将行号存入map对象的值中。map对象的值是一个set,保证保存的行号无重复。所以即使一行中出现多个重复的单词,也只保存一个行号。
std::map<std::string, std::set<line_no_type>> BuildMap(std::ifstream &input_stream, std::vector<std::string> &file){std::string word;std::string text;std::map<std::string, std::set<line_no_type>> word_map;while (getline(input_stream, text)) {file.push_back(text);auto line_no = file.size();std::istringstream line(text); while (line >> word) {auto &set_no = word_map[word]; //注意是引用,这样才能将元素添加到原set中去set_no.insert(line_no);}}return word_map;}
1)输入要查找的单词,然后用关联容器的find()查找。如果给定的单词在容器中找到,就返回一个指向关键字为给定单词的元素的迭代器,否则返回尾后迭代器。因为容器是map,所以返回一个指向pair的迭代器。
2)如果找到,则set的元素个数就是单词出现的次数。然后从set提取单词所在的行号,用这个行号作为vector的下标去提取vector对象中的文本。(行号减去1才是正确的下标)
void RunQuery(const std::map<std::string, std::set<line_no_type>> &word_map, const std::vector<std::string> &file){std::string word;while (true) {std::cout << "输入你要查询的单词(q 退出): ";std::cin >> word;if (word == "q")break;auto iter = word_map.find(word); //返回一个指向pair的迭代器if (iter != word_map.end()) {std::cout << "单词 " << word << " 出现 " << iter->second.size() << " 次" << std::endl;for (auto index : iter->second)std::cout << "\t(第 " << index << " 行)" << file[index - 1] << std::endl; //提取文本的时候要将index - 1}elsestd::cout << "单词 " << word << " 出现 0 次"<< std::endl;}}
#include <iostream>#include <sstream>#include <fstream>#include <cstdlib>#include <string>#include <vector>#include <map>#include <set>using line_no_type = std::vector<std::string>::size_type;std::map<std::string, std::set<line_no_type>> BuildMap(std::ifstream &input_stream, std::vector<std::string> &file);void RunQuery(const std::map<std::string, std::set<line_no_type>> &word_map, const std::vector<std::string> &file);int main(int argc, char **argv){if (argc != 2) {std::cout << "缺少参数" << std::endl;exit(EXIT_FAILURE);}std::vector<std::string> file;std::ifstream input_stream(argv[1]);auto word_map = BuildMap(input_stream, file);RunQuery(word_map, file);return 0;}void RunQuery(const std::map<std::string, std::set<line_no_type>> &word_map, const std::vector<std::string> &file){std::string word;while (true) {std::cout << "输入你要查询的单词(q 退出): ";std::cin >> word;if (word == "q")break;auto iter = word_map.find(word); //返回一个指向pair的迭代器if (iter != word_map.end()) {std::cout << "单词 " << word << " 出现 " << iter->second.size() << " 次" << std::endl;for (auto index : iter->second)std::cout << "\t(第 " << index << " 行)" << file[index - 1] << std::endl; //提取文本的时候要将index - 1}elsestd::cout << "单词 " << word << " 出现 0 次"<< std::endl;}}std::map<std::string, std::set<line_no_type>> BuildMap(std::ifstream &input_stream, std::vector<std::string> &file){std::string word;std::string text;std::map<std::string, std::set<line_no_type>> word_map;while (getline(input_stream, text)) {file.push_back(text);auto line_no = file.size();std::istringstream line(text); while (line >> word) {auto &set_no = word_map[word]; //注意是引用,这样才能将元素添加到原set中去set_no.insert(line_no);}}return word_map;}
- C++Primer 【笔记】文本查询程序 TextQuery
- C++primer学习:文本查询程序
- c++学习笔记-文本查询程序
- c++学习笔记:文本查询程序
- 文本查询程序--摘自c++primer
- 【足迹C++primer】41、文本查询程序
- 【足迹C++primer】56、文本查询程序
- 文本查询程序(C++primer5th)
- C++primer学习:面向对象程序设计(5):再探文本查询程序
- 【C++ Primer】【学习笔记】【第十章】关联容器之:文本查询程序
- c程序学习笔记
- 简单文本查询程序
- 文本查询程序
- 感悟:文本查询程序
- 文本查询程序
- 文本查询程序
- 文本查询程序
- 文本查询程序
- 网络优化之MobileNet
- 安卓智能地图开发与实施二十二:展示三维场景
- Unity3D
- ELF函数重定位问题
- python自学的一些小经验
- c++学习笔记:文本查询程序
- 多个域名如何使用同一个微信支付账号?(web移动端)
- Maven环境搭建和介绍
- HTML滚动链接显示
- VGGNet笔记
- Spring声明式事务配置管理方法
- 模拟手机与SIM卡的组合关系
- ViewPager加载Fragment懒加载
- 图的遍历