Chinaunix首页 | 论坛 | 博客
  • 博客访问: 491981
  • 博文数量: 59
  • 博客积分: 86
  • 博客等级: 民兵
  • 技术积分: 2141
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-30 20:57
个人简介

为今天而努力的人很平凡,为昨天而努力的人叫失败,只有为美好明天而战斗不止才叫精彩!

文章分类

全部博文(59)

文章存档

2015年(1)

2014年(3)

2013年(53)

2012年(2)

我的朋友

分类: C/C++

2013-06-07 20:56:58

    程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找单词。查询的结果是该单词出现的次数,并列出每次出现所在的行。如果某单词在同一行中多次,程序将只显示改行一次。行号按升序显示。


点击(此处)折叠或打开

  1. /*
  2.     首先列出程序所涉及的操作
  3. 1.必须允许用户指明要处理的文件名字。程序将存储该文件的内容,以便输出每个单词所在的原始行。
  4. 2.必须将每一行分解为各个单词,并记录每个单词所在的所有行。在输出行号是,应保证以升序输出,并且不重复。
  5. 3.对特定单词的查询将返回出现该单词的所有行的行号。
  6. 4.输出某单词所在的行文本时,程序必须能根据给定的行号从输入文件中获取相应的行。
  7.     数据结构
  8. . 使用一个vector<string>类型的对象存储整个输入文件的副本。输入文件的每一行是该vector对象的一个元素。
  9.     因而,在希望输出某一行时,只需要以行号为下标获取该行所在的元素即可。
  10. . 将每个单词所在的行号存储在一个set容器对象中。使用set就可确保每行只有一个条目,而且行号将自动按升序排列。
  11. . 使用一个map容器将每个单词与一个set容器对象关联起来,该set容器对象记录此单词所在的所有行号。
  12.     操作接口
  13. ·read_file成员函数,其形参为一个ifstream&类型对象。该函数每次从文件中读入行,并将它保存在vector容器中。
  14.   输入完毕后,read_file将创建关联每个单词及其所在行号的map容器。
  15. ·run_query成员函数,其形参为一个string类型对象,返回一个set对象,该set对象包含出现该string对象的所有行的行号。
  16. ·text_line成员函数,其形参为一个行号,返回输入文本中该行对应的文本行。
  17. ·store_file函数读入文件,并将文件内容存储在vector容器对象中。
  18. ·builde_map函数将每一行分解为各个单词,创建map容器对象,同时记录每个单词出现的行号。
  19. */
  20. #include<iostream>
  21. #include<string>
  22. #include<vector>
  23. #include<sstream>
  24. #include<map>
  25. #include<set>
  26. #include<fstream>

  27. using namespace std;

  28. class TextQuery{
  29. public:
  30.     typedef std::vector<std::string>::size_type line_no;
  31.     void read_file(std::ifstream &is){
  32.         store_file(is);
  33.         build_map();
  34.     }
  35.     std::set<line_no> run_query(const std::string &) const;
  36.     std::string text_line(line_no) const;
  37.     
  38. private:
  39.     void store_file(ifstream &);
  40.     void build_map();
  41.     std::vector<std::string> lines_of_text;
  42.     std::map<std::string,std::set<line_no> > word_map;
  43. };

  44. ifstream& open_file(std::ifstream &in,const std::string &file){
  45.     in.close();
  46.     in.clear();
  47.     in.open(file.c_str());
  48.     return in;
  49. }

  50. string make_plural(size_t ctr,const string &word,const string &ending){
  51.     return (ctr==1)?word:word+ending;
  52. }

  53. void print_results(const set<TextQuery::line_no>& locs,const string& sought,const TextQuery &file){
  54.     typedef set<TextQuery::line_no> line_nums;
  55.     line_nums::size_type size=locs.size();
  56.     cout<<"n"<<sought<<" occurs "<<size<<" "<<make_plural(size,"time","s")<<endl;
  57.     line_nums::const_iterator it=locs.begin();
  58.     for(;it!=locs.end();++it){
  59.         cout<<"t(line"<<(*it)+1<<")"<<file.text_line(*it)<<endl;
  60.     }
  61. }

  62. int main(int argc,char **argv[])
  63.     ifstream infile;
  64.     if(argc<2||!open_file(infile,argv[1])){/*argv[1]是文本内容所在的文件名*/
  65.         cerr<<"No input file!"<<endl;
  66.         return EXIT_FAILURE;
  67.     }
  68.     TextQuery tq;
  69.     tq.read_file(infile);
  70.     while(true)
  71.     {
  72.         cout<<"enter word to look for,or q to quit:";
  73.         string s;
  74.         cin>>s;
  75.         if(!cin||s=="q") break;
  76.         set<TextQuery::line_no> locs=tq.run_query(s);
  77.         print_results(locs,s,tq);
  78.     }
  79. return 0;
  80. }

  81. void TextQuery::store_file(ifstream &is){
  82.     string textline;
  83.     while(getline(is,textline))
  84.         lines_of_text.push_back(textline);
  85. }

  86. void TextQuery::build_map(){
  87.     for(line_no line_num=0;line_num!=lines_of_text.size();++line_num){
  88.         istringstream line(lines_of_text[line_num]);
  89.         string word;
  90.         while(line>>word)
  91.             word_map[word].insert(line_num);
  92.     }
  93. }

  94. set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const{
  95.     map<string,set<line_no> >::const_iterator loc=word_map.find(query_word);
  96.     if(loc==word_map.end())
  97.         return set<line_no>();
  98.     else
  99.         return loc->second;
  100. }

  101. string TextQuery::text_line(line_no line) const{
  102.     if(line<lines_of_text.size())
  103.         return lines_of_text[line];
  104.     throw std::out_of_range("line number out of range");
  105. }


阅读(1956) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~