C++关联容器综合应用:TextQuery小程序

本文介绍C++关联容器综合应用:TextQuery小程序(源自C++ Primer)。

关于关联容器的概念及介绍,请参考园子里这篇博文:http://www.cnblogs.com/cy568searchx/archive/2012/10/08/2715306.html

  1 #include<iostream>
  2 #include<fstream>
  3 #include<sstream>
  4 #include<string>
  5 #include<map>
  6 #include<vector>
  7 #include<set>
  8 using namespace std;
  9 //文本查询程序
 10 class TextQuery
 11 {
 12 public:
 13     typedef vector<string>::size_type line_no;
 14 
 15     void read_file(ifstream &is)
 16     {
 17         store_file(is);
 18         build_map();
 19     }
 20     set<line_no> run_query(const string&) const;
 21     string text_line(line_no) const;
 22 private:
 23     void store_file(ifstream&);
 24     void build_map();
 25     vector<string> lines_of_text;
 26     map<string,set<line_no> > word_map;
 27 };
 28 void TextQuery::store_file(ifstream &is)
 29 {
 30     string textline;
 31     while(getline(is,textline))
 32         lines_of_text.push_back(textline);
 33 }
 34 void TextQuery::build_map()
 35 {
 36     //process each line
 37     for(line_no line_num=0;line_num!=lines_of_text.size();++line_num)
 38     {
 39         istringstream line(lines_of_text[line_num]);
 40         string word;
 41         while(line>>word)
 42             //add thie line number to the set
 43             //subscript will add word to the map if it's not already there
 44             word_map[word].insert(line_num);
 45     }
 46 }
 47 set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const
 48 {
 49     //Note:must use find and not subscript the map directly
 50     //to avoid adding words to word_map!
 51     map<string,set<line_no> >::const_iterator loc=word_map.find(query_word);
 52     if(loc==word_map.end())
 53         return set<line_no>();//not found, return empty set.
 54     else
 55         return loc->second;
 56 }
 57 string TextQuery::text_line(line_no line) const
 58 {
 59     if(line<lines_of_text.size())
 60         return lines_of_text[line];
 61     throw out_of_range("line number out of range");
 62 }
 63 string make_plural(size_t ctr,const string &word,const string &ending)
 64 {
 65     return (ctr==1)?word:word+ending;
 66 }
 67 void print_results(const set<TextQuery::line_no>& locs,const string& sought,const TextQuery& file)
 68 {
 69     typedef set<TextQuery::line_no> line_nums;
 70     line_nums::size_type size=locs.size();
 71     cout<<"\n"<<sought<<" occurs "
 72         <<size<<" "
 73         <<make_plural(size,"time","s")<<endl;
 74     line_nums::const_iterator it=locs.begin();
 75     for(;it!=locs.end();++it)
 76     {
 77         cout<<"\t(line "
 78             <<(*it)+1<<") "
 79             <<file.text_line(*it)<<endl;
 80     }
 81 }
 82 ifstream& open_file(ifstream &in,const string &file)
 83 {
 84     in.close();
 85     in.clear();
 86 
 87     in.open(file.c_str());
 88     return in;
 89 }
 90 //program takes single argument specifying the file to query
 91 int main(int argc,char **argv)
 92 {
 93     ifstream infile;
 94     if(argc<2||!open_file(infile,argv[1]))
 95     {
 96         cerr<<"No input file!"<<endl;
 97         return EXIT_FAILURE;
 98     }
 99     TextQuery tq;
100     tq.read_file(infile);//build query map
101     //iterate with the user:prompt for a word to find and print results
102     //loop indefinitely;the loop exit is inside the while
103     while(true)
104     {
105         cout<<"enter word to look for, or q to quit:";
106         string s;
107         cin>>s;
108         if(!cin||s=="q") break;
109         set<TextQuery::line_no> locs=tq.run_query(s);
110         //print count and all occurrences, if any
111         print_results(locs,s,tq);
112     }
113     return 0;
114 }

运行结果:

posted on 2014-06-17 09:39  熊小熊-chris  阅读(252)  评论(0编辑  收藏  举报

导航