本文介绍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 }
运行结果: