//Successfully test on Dev-C++ under standard of ISO C++11 #include #include #include #include #include #include #include #include #include using namespace std; typedef vector::size_type line_number; typedef pair PAIR; //map's pair bool cmp_by_value(const PAIR& lhs, const PAIR& rhs) {return lhs.second > rhs.second;} struct CmpByValue //ascend sort(used in algorithm: sort()) { bool operator()(const PAIR& lhs, const PAIR& rhs) {return lhs.second > rhs.second;} }; class FileQuery //define FileQuery { private: vector sentences; //record full text map*> word_map; //record occurance line no. of each word map word_occur; //record occurance time of each word public: FileQuery() {} //default constructor FileQuery(char* a) {read_file(a);} //constructor with parameters(read file directly) ~FileQuery() //destructor { for(int i=0;i *line=word_lines.second; delete line; } for(const auto& word_occurs:word_occur) { long long unsigned int *occur=word_occurs.second; //mind the type of "occur" delete occur; } } void handle_file(string& str) //preproccess { int index=1; while(index != -1) //only words(char) and spaces remain after loop { index = str.find_first_of(",.:;!-"); if(index == -1) break; str.replace(index, 1, ""); } transform(str.begin(), str.end(), str.begin(), ::tolower); //convert uppercase letters to lowercase letters } void create_map(string& str) //create word_map and word_occur { istringstream line(str); string word; while(line>>word) //for each word { auto &lines1=word_map[word]; auto &lines2=word_occur[word]; if(!lines1) lines1 = new set; if(!lines2) lines2 = new long long unsigned int(0); lines1->insert(sentences.size()-1); ++(*lines2); } } void read_file(char* a) //read file "poem.txt"(familiar proccesses in "MyShape.cpp") { ifstream fin; ofstream fout; fin.open(a, ios::in); if(!fin) { cout<<"ERROR!"<& str_vec) {for(auto i=str_vec.begin();i!=str_vec.end();++i) cout<<*i< str_vec; //copy, which is actually transformation from string* to string for(int i=0;i*>::iterator it=word_map.begin();it!=word_map.end();++it) cout<first<<": "<<*word_occur[it->first]<first]"(see notes at line 93). "map*>::iterator" is real form of "auto" here void print_top(int n) { map map_num; for(auto i=word_map.begin();i!=word_map.end();++i) map_num.insert(pair(i->first, i->second->size())); vector map_vec(map_num.begin(),map_num.end()); //vector map_vec(word_occur.begin(),word_occur.end()); (a matter of int/long long unsigned int) sort(map_vec.begin(), map_vec.end(), CmpByValue()); //ascend sort for(int i=0;ibegin();j!=word_map[word]->end();++j) //print as: "{front_word word next_word}" (if front_word or next_word exist) { int index=1, index2=1; string str=*sentences[*j]; while(index != -1) //such a complex proccess will be much more comprehensible if a simply concrete example is given { index = str.find(word+" "); if(index == -1) break; cout<<"{"; if(index) { index2 = str.rfind(" ", index-2); cout<begin();i!=word_map[a]->end();++i) cout<<" line "<<*i+1<<":\t"<<*sentences[*i]<find(old_word); if(index == -1) break; if(!index) sentences[i]->replace(index, old_word.size(), new_word); else { index = sentences[i]->find(" "+old_word+" "); if(index == -1) break; sentences[i]->replace(index+1, old_word.size(), new_word); } } } cout<<"Replace completed!"<