您的位置:首页 > 编程语言 > C语言/C++

整理的C++ primer TextQuery 例题

2008-01-05 01:41 369 查看



/**/////// TextQuery.cpp






/**//*


* This file contains code from "C++ Primer, Fourth Edition", by Stanley B.


* Lippman, Jose Lajoie, and Barbara E. Moo, and is covered under the


* copyright and warranty notices given in that book:


*


* "Copyright (c) 2005 by Objectwrite, Inc., Jose Lajoie, and Barbara E. Moo."


*


*


* "The authors and publisher have taken care in the preparation of this book,


* but make no expressed or implied warranty of any kind and assume no


* responsibility for errors or omissions. No liability is assumed for


* incidental or consequential damages in connection with or arising out of the


* use of the information or programs contained herein."


*


* Permission is granted for this code to be used for educational purposes in


* association with the book, given proper citation if and when posted or


* reproduced.Any commercial use of this code requires the explicit written


* permission of the publisher, Addison-Wesley Professional, a division of


* Pearson Education, Inc. Send your request for permission, stating clearly


* what code you would like to use, and in what specific way, to the following


* address:


*


* Pearson Education, Inc.


* Rights and Contracts Department


* 75 Arlington Street, Suite 300


* Boston, MA 02216


* Fax: (617) 848-7047


*/




#include "TextQuery.h"


#include <sstream>


#include <string>


#include <vector>


#include <map>


#include <set>


#include <iostream>


#include <fstream>


#include <cctype>


#include <cstring>


#include <stdexcept>




using std::istringstream;


using std::set;


using std::string;


using std::getline;


using std::map;


using std::vector;


using std::cerr;


using std::cout;


using std::cin;


using std::ifstream;


using std::endl;


using std::ispunct;


using std::tolower;


using std::strlen;


using std::out_of_range;




string TextQuery::text_line(line_no line) const




...{


if (line < lines_of_text.size())


return lines_of_text[line];


throw std::out_of_range("line number out of range");


}




// read input file: store each line as element in lines_of_text


void TextQuery::store_file(ifstream &is)




...{


string textline;


while (getline(is, textline))


lines_of_text.push_back(textline);


}




// : vertical tab; : formfeed; : carriage return are


// treated as whitespace characters along with space, tab and newline


string TextQuery::whitespace_chars(" ");




// finds whitespace-separated words in the input vector


// and puts the word in word_map along with the line number


void TextQuery::build_map()




...{


// process each line from the input vector


for (line_no line_num = 0;


line_num != lines_of_text.size();


++line_num)




...{


// we'll use line to read the text a word at a time


istringstream line(lines_of_text[line_num]);


string word;


while (line >> word)


// add this line number to the set;


// subscript will add word to the map if it's not already there


word_map[cleanup_str(word)].insert(line_num);


}


}




set<TextQuery::line_no>


TextQuery::run_query(const string &query_word) const




...{


// Note: must use find and not subscript the map directly


// to avoid adding words to word_map!


map<string, set<line_no> >::const_iterator


loc = word_map.find(cleanup_str(query_word));


if (loc == word_map.end())


return set<line_no>(); // not found, return empty set


else


// fetch and return set of line numbers for this word


return loc->second; // It's also a set of line numbers


}




void TextQuery::display_map()




...{


map< string, set<line_no> >::iterator iter = word_map.begin(),


iter_end = word_map.end();




// for each word in the map




for ( ; iter != iter_end; ++iter) ...{


cout << "word: " << iter->first << " {";




// fetch location vector as a const reference to avoid copying it


const set<line_no> &text_locs = iter->second; // a reference to the set in the map


set<line_no>::const_iterator loc_iter = text_locs.begin(),


loc_iter_end = text_locs.end();




// print all line numbers for this word


while (loc_iter != loc_iter_end)




...{


cout << *loc_iter;




if (++loc_iter != loc_iter_end)


cout << ", ";




}




cout << "} "; // end list of output this word


}


cout << endl; // finished printing entire map


}




string TextQuery::cleanup_str(const string &word)




...{


string ret;




for (string::const_iterator it = word.begin(); it != word.end(); ++it) ...{


if (!ispunct(*it))


ret += tolower(*it);


}


return ret;


}












/**/////////////////////////////////////////////////


// TextQuery.h




/**//*


* This file contains code from "C++ Primer, Fourth Edition", by Stanley B.


* Lippman, Jose Lajoie, and Barbara E. Moo, and is covered under the


* copyright and warranty notices given in that book:


*


* "Copyright (c) 2005 by Objectwrite, Inc., Jose Lajoie, and Barbara E. Moo."


*


*


* "The authors and publisher have taken care in the preparation of this book,


* but make no expressed or implied warranty of any kind and assume no


* responsibility for errors or omissions. No liability is assumed for


* incidental or consequential damages in connection with or arising out of the


* use of the information or programs contained herein."


*


* Permission is granted for this code to be used for educational purposes in


* association with the book, given proper citation if and when posted or


* reproduced.Any commercial use of this code requires the explicit written


* permission of the publisher, Addison-Wesley Professional, a division of


* Pearson Education, Inc. Send your request for permission, stating clearly


* what code you would like to use, and in what specific way, to the following


* address:


*


* Pearson Education, Inc.


* Rights and Contracts Department


* 75 Arlington Street, Suite 300


* Boston, MA 02216


* Fax: (617) 848-7047


*/




#ifndef TEXTQUERY_H


#define TEXTQUERY_H


#include <string>


#include <vector>


#include <map>


#include <set>


#include <iostream>


#include <fstream>


#include <cctype>


#include <cstring>






class TextQuery ...{


// as before


public:


// typedef to make declarations easier


typedef std::string::size_type str_size;


typedef std::vector<std::string>::size_type line_no;






/**//* interface:


* read_file builds internal data structures for the given file


* run_query finds the given word and returns set of lines on which it appears


* text_line returns a requested line from the input file


*/


void read_file(std::ifstream &is)




...{ store_file(is); build_map(); }


std::set<line_no> run_query(const std::string&) const;


std::string text_line(line_no) const;




str_size size() const ...{ return lines_of_text.size(); }


void display_map(); // debugging aid: print the map




private:


// utility functions used by read_file


void store_file(std::ifstream&); // store input file


void build_map(); // associated each word with a set of line numbers




// remember the whole input file


std::vector<std::string> lines_of_text;




// map word to set of the lines on which it occurs


std::map< std::string, std::set<line_no> > word_map;


// characters that constitute whitespace


static std::string whitespace_chars;


// canonicalizes text: removes punctuation and makes everything lower case


static std::string cleanup_str(const std::string&);


};


#endif








/**////////////////////////////////////////////


// main function


//WordCount.cpp




/**//*


* This file contains code from "C++ Primer, Fourth Edition", by Stanley B.


* Lippman, Jose Lajoie, and Barbara E. Moo, and is covered under the


* copyright and warranty notices given in that book:


*


* "Copyright (c) 2005 by Objectwrite, Inc., Jose Lajoie, and Barbara E. Moo."


*


*


* "The authors and publisher have taken care in the preparation of this book,


* but make no expressed or implied warranty of any kind and assume no


* responsibility for errors or omissions. No liability is assumed for


* incidental or consequential damages in connection with or arising out of the


* use of the information or programs contained herein."


*


* Permission is granted for this code to be used for educational purposes in


* association with the book, given proper citation if and when posted or


* reproduced.Any commercial use of this code requires the explicit written


* permission of the publisher, Addison-Wesley Professional, a division of


* Pearson Education, Inc. Send your request for permission, stating clearly


* what code you would like to use, and in what specific way, to the following


* address:


*


* Pearson Education, Inc.


* Rights and Contracts Department


* 75 Arlington Street, Suite 300


* Boston, MA 02216


* Fax: (617) 848-7047


*/




#include "TextQuery.h"


#include <string>


#include <vector>


#include <map>


#include <set>


#include <iostream>


#include <fstream>


#include <cctype>


#include <cstring>


#include <cstdlib>




using std::set;


using std::string;


using std::map;


using std::vector;


using std::cerr;


using std::cout;


using std::cin;


using std::ifstream;


using std::endl;


using std::ends;




string make_plural(size_t, const string&, const string&);


ifstream& open_file(ifstream&, const string&);


ifstream& close_file(ifstream&);


void print_results(const set<TextQuery::line_no>& locs,


const string& sought, const TextQuery &file)




...{


// if the word was found, then print count and all occurrences


typedef set<TextQuery::line_no> line_nums;


line_nums::size_type size = locs.size();


cout << " " << sought << " occurs "


<< size << " "


<< make_plural(size, "time", "s") << endl;




// print each line in which the word appeared


line_nums::const_iterator it = locs.begin();




for ( ; it != locs.end(); ++it) ...{


cout << " (line "


// don't confound user with text lines starting at 0


<< (*it) + 1 << ") "


<< file.text_line(*it) << endl;


}


}




// program takes single argument specifying the file to query


int main()




...{


// open the file from which user will query words


ifstream infile;


string fname;


cout<<"Please input file name which wanted to query:"<<ends;


cin>>fname;


if(!open_file(infile,fname))




...{


cerr<<"Open file error!"<<endl;


return EXIT_FAILURE;


}




TextQuery tq;


tq.read_file(infile); // builds query map




close_file(infile);




// iterate with the user: prompt for a word to find and print results


// loop indefinitely; the loop exit is inside the while




while (true) ...{


cout << " enter word to look for, or q to quit: ";


string s;


cin >> s;




// stop if hit eof on input or a 'q' is entered


if (!cin || s == "q"||"Q"==s) break;




// get the set of line numbers on which this word appears


set<TextQuery::line_no> locs = tq.run_query(s);




// print count and all occurrences, if any


print_results(locs, s, tq);


}


close_file(infile);


return 0;


}






string make_plural(size_t ctr,const string &word,const string &ending)




...{


// Make some modify to adjust the application


return (1==ctr||0==ctr)? word:word+ending;


}






ifstream &open_file(ifstream &in,const string &file)




...{


in.open(file.c_str());


return in;


}




ifstream &close_file(ifstream &in)




...{


in.close();


in.clear();


return in;


}



一个不错的题目,个人整理了一下,发上来保存吧。
我个人在里面做了小小的修改,但基本没有变化什么。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: