需求

程序读取用户指定的任意文本文件,允许用户从该文件中查找单词。查询结果是该单词出现的次数,并列出每次出现所在行,如果某单词在同一行中多次出现,程序将只显示该行一次。行号按升序显示,即第 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

容器的综合应用:文本查询程序相关推荐

  1. C++ 容器的综合应用的一个简单实例——文本查询程序

    [0. 需求] 最近在粗略学习<C++ Primer 4th>的容器内容,关联容器的章节末尾有个很不错的实例. 通过实现一个简单的文本查询程序,希望能够对C++的容器学习有更深的理解. 由 ...

  2. c++ primer--容器的综合应用:文本查询程序

    c++ primer–容器的综合应用:文本查询程序 我们的程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在的行.如果某单词在同一行中多 ...

  3. C++自学笔记_文本查询程序_《C++ Primer》

    <C++ Primer> 第10章结束,用一个文本查询程序结束本章 :) 程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在 ...

  4. 【Smart_Point】动态内存与智能指针实战:文本查询程序(设计set,map,智能指针的应用)

    文章目录 Cpp读入结构性数组 文本查询程序 文本查询程序本版1 Cpp读入结构性数组 #include<sstream> #include<iostream> #includ ...

  5. C++ primer 第12章 12.3 使用标准库:文本查询程序

    文章目录 使用标准库:文本查询程序 文本查询程序设计 数据结构 在类之间共享数据 自己的文本查询程序 书中的文本查询程序 使用标准库:文本查询程序 我们将实现一个简单的文本查询程序,作为标准库相关内容 ...

  6. 15.9 文本查询程序再探(继承)

    本节中使用类的继承方式重写了文本查询程序,支持多种查询策略:或,与,非. 其中Query是提供给用户使用的类,含有两个接口:eval和rep,eval用于查找对应的单词出现的文本,rep用于输出用户指 ...

  7. c++ primer文本查询程序 自编加强版(c++primer5th 练习12.32-33)

    //文件 functions.cc#include <iostream> #include <string> #include <vector> #include ...

  8. 12.3 文本查询程序

    未封装版本 #include <iostream> #include <fstream> #include <string> #include <vector ...

  9. c++primer 12.3.1文本查询程序

    提示:不完全类型只能在优先的情况下使用,可以定义以这个类型作为函数的参数类型或者函数返回值类型,也可以定义这个类型的指针或者引用. //文件functions.cc #include <stri ...

最新文章

  1. Leetcode 698. 划分为k个相等的子集 解题思路及C++实现
  2. Oralcle存储过程书写规范
  3. Inline Temp(内联临时变量)
  4. ssh-keygen实现免密码登陆
  5. 目前发展医疗物联网的困境解析
  6. 移动端UI自动化Appium测试——Appium server两种启动方式
  7. 算法设计 分治, 归并排序, 快速排序
  8. maven依赖c3p0_springboot 使用c3p0数据库连接池的方法
  9. win pe备份linux,Windows10操作系统如何使用微PE实现备份与恢复
  10. 计算机一个小键盘按不出来怎么办,巧妙解决电脑键盘右边的数字键失灵问题
  11. 如何更改iPhone备份和iTunes MobileSync备份文件夹的位置
  12. Android破解游戏内购心得
  13. 满分考生进入清华学造芯片,集成电路学院院长亲自带,网友:为中华之崛起而读书...
  14. 办公软件excel表格_国产表格神器:超脱excel,画表只是基本功能,做软件才是真本事...
  15. asp生成带参数的二维码并合成推广海报图片,asp合并合成推广海报图片asp代码
  16. TFTP协议详细分析
  17. Async await的使用
  18. 一份不错的正则入门文章
  19. 【AI简报20210730期】黑芝麻A1000 Pro自动驾驶芯片流片成功、地平线征程 5 芯片发布...
  20. wps上下标怎么对齐_wps如何设置表格对齐方式图解

热门文章

  1. hashtable允许null键和值吗_MySQL默认值选型是空,还是 NULL-爱可生
  2. python快速上手 让繁琐工作自动化 英文版_入门python:《Python编程快速上手让繁琐工作自动化》中英文PDF+代码...
  3. 『设计模式』一句话教你分清楚UML组合聚合和联系!
  4. 迷你5和迷你4区别_可变大小的视频迷你批处理
  5. 模糊图像处理 去除模糊_图像模糊如何工作
  6. C++初始编程及相关的问题总结
  7. 直击于丹软肋的作家——李悦
  8. CSS和JavaScript在线代码压缩工具推荐
  9. oracle空值判断 =,Oracle,sql server的空值(null)判断
  10. jap和java有关系吗_hibernate与jpa有什么区别和联系?