容器的综合应用:文本查询程序
需求
程序读取用户指定的任意文本文件,允许用户从该文件中查找单词。查询结果是该单词出现的次数,并列出每次出现所在行,如果某单词在同一行中多次出现,程序将只显示该行一次。行号按升序显示,即第 7 行应该在第 9 行之前输出,依此类推。例如,以本章的内容作为文件输入,然后查找单词“element”。输出的前几行应为:
element occurs 125 times
(line 62) element with a given key.
(line 64) second element with the same key.
(line 153) element |==| operator.
(line 250) the element type.
(line 398) corresponding element.
后面省略了大约 120 行。
看着书上的例子,自己写了下,大致思路是
读取文件,将文件以行为单位,放入vector<string>,再遍历vector<string>,将每行每个单词读入map< string,set<unsigned> >中,最后从map中查找读取
注意的地方
程序是不区分大小写的,还需要去掉文章中的标点需要调用函数
头文件#include<cctype>
ispunct() 检查是否是非空格、非数字和非英文字母,类似函数isspace,isdigit,isalpha
tolower() 把字符转换成小写字母
对const成员的迭代器需要用const_iterator
对于内置类型,和长度比较短(8字节以内)的浅层结构,类等对象,传值比传引用效率更高。
对超过8字节的对象,一般传引用效率更高。
但实际上传引用或传值的选择,主要取决于功能需求而非效率需求。
详解
获取文件对象:
1 ifstream& open_file(ifstream &in,const string &file) 2 { 3 in.close(); 4 in.clear(); 5 in.open(file.c_str()); 6 return in; 7 }
读文件,创建vector和map
1 void TextQuery::read_file(ifstream &in) 2 { 3 store_file(in); 4 build_map(); 5 } 6 7 void TextQuery::store_file(ifstream &in) 8 { 9 string textline; 10 while(getline(in,textline)) 11 lines_of_text.push_back(textline); 12 } 13 14 void TextQuery::build_map() 15 { 16 for(line_no line_num = 0;line_num != lines_of_text.size();line_num++) 17 { 18 istringstream line(lines_of_text[line_num]); 19 string word; 20 while(line >> word) 21 { 22 word = cleanup_str(word); 23 word_map[word].insert(line_num); 24 } 25 26 } 27 }
处理单词中的符号,忽略大小写
1 string TextQuery::cleanup_str(const string &word) 2 { 3 string ret; 4 for(string::const_iterator it = word.begin();it != word.end();++it) 5 { 6 if(!ispunct(*it)) 7 ret += tolower(*it); 8 } 9 return ret; 10 }
查找单词,返回值是map的第二个元素set,用来保存单词所在的行号
1 set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const 2 { 3 map< string,set<line_no> >::const_iterator loc = word_map.find(query_word); 4 if( loc == word_map.end() ) 5 return set<line_no>(); //找不到返回空的set对象 6 else 7 return loc ->second; 8 }
返回查找结果,这里有个漏洞,查找单词的数目是为单词所出现的行数(因为set不存储重复元素)
void TextQuery::print_result(set<line_no> locs,const string &query_word) {cout<<query_word<<":"<<locs.size()<<endl;set<line_no>::iterator it = locs.begin();while(it != locs.end()){cout<<"(line "<<*it+1<<") ";cout<<lines_of_text[*it]<<endl;it++;} }
写了两个辅助函数,并未调用,为了查看vector和map中的内容
1 void TextQuery::show_vec() 2 { 3 vector<string>::iterator ite = lines_of_text.begin(); 4 while(ite != lines_of_text.end()) 5 cout<<*ite++<<endl; 6 } 7 void TextQuery::show_map() 8 { 9 map< string,set<line_no> >::iterator loc = word_map.begin(); 10 while(loc != word_map.end()) 11 { 12 cout<<loc->first<<"\t"; 13 set<line_no>::iterator it = (loc->second).begin(); 14 while(it != (loc->second).end()) 15 { 16 cout<<*it + 1<<" "; 17 it++; 18 } 19 cout<<endl; 20 loc++; 21 } 22 }
运行结果
代码点此下载
转载于:https://www.cnblogs.com/raichen/p/4900308.html
容器的综合应用:文本查询程序相关推荐
- C++ 容器的综合应用的一个简单实例——文本查询程序
[0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例. 通过实现一个简单的文本查询程序,希望能够对C++的容器学习有更深的理解. 由 ...
- c++ primer--容器的综合应用:文本查询程序
c++ primer–容器的综合应用:文本查询程序 我们的程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在的行.如果某单词在同一行中多 ...
- C++自学笔记_文本查询程序_《C++ Primer》
<C++ Primer> 第10章结束,用一个文本查询程序结束本章 :) 程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在 ...
- 【Smart_Point】动态内存与智能指针实战:文本查询程序(设计set,map,智能指针的应用)
文章目录 Cpp读入结构性数组 文本查询程序 文本查询程序本版1 Cpp读入结构性数组 #include<sstream> #include<iostream> #includ ...
- C++ primer 第12章 12.3 使用标准库:文本查询程序
文章目录 使用标准库:文本查询程序 文本查询程序设计 数据结构 在类之间共享数据 自己的文本查询程序 书中的文本查询程序 使用标准库:文本查询程序 我们将实现一个简单的文本查询程序,作为标准库相关内容 ...
- 15.9 文本查询程序再探(继承)
本节中使用类的继承方式重写了文本查询程序,支持多种查询策略:或,与,非. 其中Query是提供给用户使用的类,含有两个接口:eval和rep,eval用于查找对应的单词出现的文本,rep用于输出用户指 ...
- c++ primer文本查询程序 自编加强版(c++primer5th 练习12.32-33)
//文件 functions.cc#include <iostream> #include <string> #include <vector> #include ...
- 12.3 文本查询程序
未封装版本 #include <iostream> #include <fstream> #include <string> #include <vector ...
- c++primer 12.3.1文本查询程序
提示:不完全类型只能在优先的情况下使用,可以定义以这个类型作为函数的参数类型或者函数返回值类型,也可以定义这个类型的指针或者引用. //文件functions.cc #include <stri ...
最新文章
- Leetcode 698. 划分为k个相等的子集 解题思路及C++实现
- Oralcle存储过程书写规范
- Inline Temp(内联临时变量)
- ssh-keygen实现免密码登陆
- 目前发展医疗物联网的困境解析
- 移动端UI自动化Appium测试——Appium server两种启动方式
- 算法设计 分治, 归并排序, 快速排序
- maven依赖c3p0_springboot 使用c3p0数据库连接池的方法
- win pe备份linux,Windows10操作系统如何使用微PE实现备份与恢复
- 计算机一个小键盘按不出来怎么办,巧妙解决电脑键盘右边的数字键失灵问题
- 如何更改iPhone备份和iTunes MobileSync备份文件夹的位置
- Android破解游戏内购心得
- 满分考生进入清华学造芯片,集成电路学院院长亲自带,网友:为中华之崛起而读书...
- 办公软件excel表格_国产表格神器:超脱excel,画表只是基本功能,做软件才是真本事...
- asp生成带参数的二维码并合成推广海报图片,asp合并合成推广海报图片asp代码
- TFTP协议详细分析
- Async await的使用
- 一份不错的正则入门文章
- 【AI简报20210730期】黑芝麻A1000 Pro自动驾驶芯片流片成功、地平线征程 5 芯片发布...
- wps上下标怎么对齐_wps如何设置表格对齐方式图解
热门文章
- hashtable允许null键和值吗_MySQL默认值选型是空,还是 NULL-爱可生
- python快速上手 让繁琐工作自动化 英文版_入门python:《Python编程快速上手让繁琐工作自动化》中英文PDF+代码...
- 『设计模式』一句话教你分清楚UML组合聚合和联系!
- 迷你5和迷你4区别_可变大小的视频迷你批处理
- 模糊图像处理 去除模糊_图像模糊如何工作
- C++初始编程及相关的问题总结
- 直击于丹软肋的作家——李悦
- CSS和JavaScript在线代码压缩工具推荐
- oracle空值判断 =,Oracle,sql server的空值(null)判断
- jap和java有关系吗_hibernate与jpa有什么区别和联系?