Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25314
  • 博文数量: 33
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2015-10-06 22:37
文章分类
文章存档

2015年(33)

我的朋友
最近访客

分类: C/C++

2015-10-11 21:28:11

     学习了几种顺序容器和关联容器,就有一种想编写代码练习的冲动,于是就选择了书上的示例程序来练手,没想到自己第一次真正编写面向对象的程序时这样坎坷不顺,整个思维都无法适应,各式各样的::作用符错误让自己头都大了,就这样中断了两次(实在写不下去了),今天才终于勉强写完编译通过,但是还没有运行测试。不行了,没有体力了,面向对象这么难么?
     自己的程序时一个文本查询程序,输入一个文件参数,输入一个keyword,程序应当可以给出keyword在文中出现的次数以及列出每个出现的行内容。整体的数据结构采用一个TextQuery类来实现,实现的操作有Read_File/Run_Query/Print_Results三个成员函数,采用默认构造函数。数据结构上将文件内容按行存入vector,然后建立每个单词与出现行数的map,出现的行数用set来组织,可以有效避免重复。至于查找,我们使用的是map自带的find函数操作实现,回避了自己编写find函数的需要。
首先是头文件TQ.h

点击(此处)折叠或打开

  1. #include <iostream>
  2. #include <fstream>
  3. #include <sstream>
  4. #include <string>
  5. #include <cstdlib>
  6. #include <vector>
  7. #include <set>
  8. #include <map>

  9. class TextQuery
  10. {
  11. public:
  12.     //定义一个类型别名,简化编程
  13.     typedef std::vector<std::string>::size_type line_no;
  14.     void Read_File(std::ifstream& ifs)
  15.     {
  16.         Store_File(ifs);
  17.         Build_Map();
  18.     }
  19.     std::set< line_no > Run_Query(const std::string keyword);
  20.     std::string Print_Results( line_no );

  21. private:
  22.     std::vector<std::string> lines_of_text; //按行存储目标文件
  23.     std::map< std::string, std::set<line_no> > word_map;
  24.     void Store_File(std::ifstream& ifs);
  25.     void Build_Map();
  26. };

     然后是类的实现函数TextQuery.cpp

点击(此处)折叠或打开

  1. #include "TQ.h"

  2. using namespace std;
  3. //按行存储文件到vector
  4. void TextQuery::Store_File(ifstream& ifs)
  5. {
  6.     string textline;
  7.     while (getline(ifs, textline))
  8.         lines_of_text.push_back(textline);
  9. }

  10. //建立文件中每个单词和其所在行set容器的map
  11. void TextQuery::Build_Map()
  12. {
  13.     for (line_no line_num = 0; line_num < lines_of_text.size(); line_num++)
  14.     {
  15.         istringstream line(lines_of_text[line_num]);
  16.         string word;
  17.         while (line >> word)
  18.             word_map[word].insert(line_num); //set容器中的元素不重复
  19.     }
  20. }

  21. std::set<std::vector<string>::size_type> TextQuery::Run_Query(const string keyword)
  22. {
  23.     map<string, set<line_no> >::const_iterator loc = word_map.find(keyword);
  24.     if (loc == word_map.end())
  25.         return set<line_no>();
  26.     else
  27.         return loc->second;
  28. }
  29. //根据行号打印该行对应的文本
  30. string TextQuery::Print_Results(TextQuery::line_no line_num)
  31. {
  32.     if (line_num < lines_of_text.size())
  33.         return lines_of_text[line_num];
  34.     else
  35.         throw out_of_range("line number out of range");
  36. }
      最后是main函数

点击(此处)折叠或打开

  1. #include "TQ.h"

  2. using namespace std;

  3. void cout_results(const set<TextQuery::line_no>& locs, const string& str, TextQuery &file)
  4. {
  5.     //if the word was found, the print count and all lines
  6.     typedef set<TextQuery::line_no> line_nums;
  7.     line_nums::size_type size = locs.size();
  8.     cout << "\n" <<str<< " occurs "
  9.          << size << " "
  10.             << "times" << endl;
  11.     //print each line in which the word appeared
  12.     line_nums::const_iterator it = locs.begin();
  13.     for (; it != locs.end(); it++)
  14.     {
  15.         cout << "\t(line "
  16.                 << (*it) + 1
  17.                 << " )"
  18.                 << file.Print_Results(*it)<< endl;
  19.     }
  20. }

  21. int main(int argc, char *argv[])
  22. {
  23.     //打开目标文件
  24.     ifstream infile;
  25.     if (argc < 2 )
  26.     {
  27.         cerr << "No input file!"<<endl;
  28.         return -1;
  29.     }
  30.     infile.open(argv[1]);
  31.     TextQuery tq;
  32.     tq.Read_File(infile);
  33.     //循环与用户交互提示输入要查找的关键词
  34.     while (true)
  35.     {
  36.         cout << "enter word to look for, or q to quit:"<<endl;
  37.         string key;
  38.         cin >> key;
  39.         if (!cin)
  40.             break;
  41.         set<TextQuery::line_no> locs = tq.Run_Query(key);
  42.         //print count and all occurrences if any
  43.         cout_results(locs, key, tq);
  44.     }
  45.     system("pause");
  46.     return 0;
  47. }
      编译时通过了,但是没有进行运行测试。
     第一次感觉写面向对象程序,感觉不知道如何组织程序,有种按照步骤一步一步解决的思维惯性,这方面给自己造成了较大的困扰。另一方面自己对于容器的部分还掌握的不够扎实,因此遇到许多编译错误,自己不晓得是什么问题,如何解决。
.面向程序设计首先要确定分析的对象,这个对象可以是实体,如飞机、人等,也可以是非实体,如文本查询过程,图书馆系统等。
.其次要分析需要进行的操作,将这些操作划分到类内部实现还是main中实现。
.第三部需要确定数据结构,比如本例要考虑借助vector/map/set三种容器类型来组织数据。
.第四步要写出类的定义以及各个成员函数的要求。
.第五步开始分布实现类,先将类的成员函数依次实现。
.第六步编写main函数,开始创建类对象,调用成员函数实现功能。
阅读(268) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~