首页 > 代码库 > C++关联容器综合应用:TextQuery小程序

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 map101     //iterate with the user:prompt for a word to find and print results102     //loop indefinitely;the loop exit is inside the while103     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 any111         print_results(locs,s,tq);112     }113     return 0;114 }

运行结果: