Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103868
  • 博文数量: 8
  • 博客积分: 467
  • 博客等级: 一等列兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-22 22:16
个人简介

追梦人

文章分类
文章存档

2013年(1)

2012年(1)

2011年(2)

2010年(4)

分类: C/C++

2013-07-01 09:59:21

        功能:程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词.查询的结果是该单词出现的次数,并列出每次出现所在的行.如果某单词在同一行中多次出现,程序将只显示该行一次.
行号按升序显示,即第7行应该在第9行之前输出,依次类推.

 程序需要支持如下任务:
(1) 它必须允许用户指明要处理的文件名字. 程序将存储该文件的内容,以便输出每个单词所在的原始行.
(2) 它必须将每一行分解为各个单词,并记录每个单词所在的所有行. 在输出行号时,应保证以升序输出,并且不重复.
(3) 对特定单词的查询将返回出现该单词的所有行的行号.
(4) 输出某单词所在的行文本时, 程序必须能根据给定的行号从输入文件中获取相应的行.
数据结构
(1)  使用一个vector类型的对象存储整个输入文件的副本, 输入文件的每一行是该vector对象的一个元素.
(2)  将每个单词所在的行号存储在一个set容器对象中.使用set就可确保每行只有一个条目,而且行号将自动按升序排列;
(3)  使用一个map容器将每个单词与一个set容器对象关联起来,该set容器对象记录此单词所在的行号.

代码:

点击(此处)折叠或打开

  1. /*************************************************************************
  2.     > File Name: textquery.cpp
  3.     > Author: wolf
  4.     > Created Time: Thu 27 Jun 2013 03:12:07 PM CST
  5.  ************************************************************************/

  6. #include<iostream>
  7. #include<fstream>
  8. #include<sstream>
  9. #include<vector>
  10. #include<map>
  11. #include<set>
  12. #include<stdexcept>
  13. #include<cstdlib>

  14. using namespace std;

  15. class TextQuery    {
  16. public:
  17.     //typedef to make declarations easier
  18.     typedef std::vector<std::string>::size_type line_no;
  19.     /*
  20.      * read_file builds internel data structures for the given file
  21.      * run_query finds the given word and returns set of lines on which it appears
  22.      * text_line returns a requested line from the input file
  23.      */
  24.      void read_file(std::ifstream &is)
  25.      { store_file(is); build_map();     }
  26.      std::set<line_no> run_query(const std::string &) const;
  27.      std::string text_line(line_no) const;

  28. private:
  29.      //utility functions used by read_file
  30.      void store_file(std::ifstream&); //store input file
  31.      void build_map(); //associated each word with a set of line numbers
  32.      //remember the whole input file
  33.      std::vector<std::string> lines_of_text;
  34.      //map word to set of the lines on which it occurs
  35.      std::map< std::string, std::set<line_no> > word_map;
  36. };

  37. // read input file: store each line as element in line_of_text
  38. void TextQuery::store_file(ifstream &is)
  39. {
  40.     string textline;
  41.     while(getline(is, textline))
  42.         lines_of_text.push_back(textline);
  43. }

  44. // fine whitespace-separated words in the input vector
  45. // and puts the word in word_map along with the line number
  46. void TextQuery::build_map()
  47. {
  48.     //process each line from the input vector
  49.     for(line_no line_num = 0; line_num != lines_of_text.size(); ++line_num)
  50.     {
  51.         //we will use line to read the text a word at a time
  52.         istringstream line(lines_of_text[line_num]);
  53.         string word;
  54.         while(line >> word)
  55.             //add this line number to the set;
  56.             //subscript will add word to the map if it's not already there
  57.             word_map[word].insert(line_num);
  58.     }
  59. }

  60. set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const
  61. {
  62.     //Note:must use find and not subscript the map directly
  63.     //to avoid adding words to word_map
  64.     map<string, set<line_no> >::const_iterator loc = word_map.find(query_word);
  65.     if(loc == word_map.end())
  66.         return set<line_no>(); //not found, return empty set
  67.     else
  68.         //fetch and return set of line numbers for this word
  69.         return loc->second;
  70. }

  71. string TextQuery::text_line(line_no line) const
  72. {
  73.     if(line < lines_of_text.size())
  74.         return lines_of_text[line];
  75.     throw std::out_of_range("line number out of range");
  76. }

  77. string make_plural(size_t ctr, const string &word, const string &ending)
  78. {
  79.     return (ctr == 1) ? word: word +ending;
  80. }

  81. ifstream& open_file(ifstream &in, const string &file)
  82. {
  83.     in.close();
  84.     in.clear();
  85.     in.open(file.c_str());
  86.     return in;
  87. }


  88. void print_results(const set<TextQuery::line_no> &locs, const string &sought, const TextQuery &file)
  89. {
  90.     //if the word was found, then print count and all occurences
  91.     typedef set<TextQuery::line_no> line_nums;
  92.     line_nums::size_type size = locs.size();
  93.     cout << "\n" <<sought << " occurs " << size << " " << make_plural(size, "time", "s") << endl;
  94.     //print each line in which the word appeared
  95.     line_nums::const_iterator it = locs.begin();
  96.     for(; it != locs.end(); it++)
  97.     {
  98.         cout << "\t(line " << (*it) + 1 << ")" << file.text_line(*it) << endl;
  99.     }
  100. }


  101. int main(int argc, char *argv[])
  102. {
  103.     ifstream infile;
  104.     if(argc < 2 || !open_file(infile, argv[1]))
  105.     {
  106.         cerr << "No input file!" << endl;
  107.         return EXIT_FAILURE;
  108.     }
  109.     TextQuery tq;
  110.     tq.read_file(infile);
  111.     while(true)    {
  112.         cout << " enter word to look for, or q to quit: ";
  113.         string s;
  114.         cin >> s;
  115.         if(!cin || s == "q") break;
  116.         set<TextQuery::line_no> locs = tq.run_query(s);
  117.         print_results(locs, s, tq);
  118.     }

  119.     return 0;
  120. }




阅读(2365) | 评论(0) | 转发(0) |
0

上一篇:龙芯2F处理器PMON的编译、加载

下一篇:没有了

给主人留下些什么吧!~~