#include <iostream> #include <fstream> #include <algorithm> #include <vector> #include <string> #include <sstream> #include <set> #include <map> using namespace std; class TextQuery { public: typedef vector<string>::size_type line_no; typedef map<string,set<line_no> > mapSet; void readFile(ifstream &is) { storeFile(is); bulitMap(); } set<line_no> runQuery(const string& word) const { mapSet::const_iterator it=wordMap.find(word); if(it==wordMap.end()) return set<line_no>(); else return it->second; } string TextLine(line_no lineNum) const { if(lineNum<lineOfText.size()) return lineOfText[lineNum]; throw std::out_of_range("line number out of range"); } private: void storeFile(ifstream &is) { string textline; while(getline(is,textline)) lineOfText.push_back(textline); } void bulitMap() { for (line_no lineNum=0;lineNum!=lineOfText.size();lineNum++) { istringstream line(lineOfText[lineNum]); string word; while(line>>word) wordMap[word].insert(lineNum); } } vector<string> lineOfText; map<string,set<line_no> > wordMap; }; ifstream& openFile(ifstream &in,const string &fileName) { in.close(); in.clear(); in.open(fileName.c_str()); return in; } string makePlural(size_t ctr,const string &words,const string & ending) { return (ctr==1)?words:words+ending; } void printResult(const set<TextQuery::line_no> &loc,const string &sought,const TextQuery &tq) { typedef set<TextQuery::line_no> line_nums; line_nums::size_type size=loc.size(); cout<<"\n"<<sought<<" occurs "<<size<<" "<<makePlural(size,"time","s")<<endl; line_nums::const_iterator con_iter=loc.begin(); for (;con_iter!=loc.end();con_iter++) { cout<<"\t(line "<<*con_iter+1<<")"<<tq.TextLine(*con_iter)<<endl; } } int main(int argc,char** argv) { ifstream inFile; //cout<<"enter the text file name"<<endl; //string fileName; //cin>>fileName; if (argc<2||!openFile(inFile,argv[1])) { cerr<<"no input file!"<<endl; return EXIT_FAILURE; } TextQuery tq; tq.readFile(inFile); while(true) { cout<<"enter word to look for,or q to quit!"<<endl; string temp; cin>>temp; if(!cin||temp=="q") break; set<TextQuery::line_no> loc=tq.runQuery(temp); printResult(loc,temp,tq); } return 0; }