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 }

运行结果:

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

你可能感兴趣的:(query)