//TextQuery.h #ifndef _TEXTQUERY_H_ #define _TEXTQUERY_H_ #include <vector> #include <fstream> #include <iostream> #include <string> #include <set> #include <map> class TextQuery{ public: typedef std::vector<std::string>::size_type line_no; 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; private: void store_file(std::ifstream&); void build_map(); std::vector<std::string> lines_of_text; std::map< std::string, std::set<line_no> > word_map; }; #endif
//TextQuery.cpp #include "TextQuery.h" #include <iostream> #include <sstream> #include <utility> using std::string; using std::vector; using std::set; using std::map; using std::istringstream; std::set<TextQuery::line_no> TextQuery::run_query(const std::string &word) const { map< string, set<line_no> >::const_iterator iter = word_map.find(word); if (iter != word_map.end()) { return iter->second; } else { set<line_no> temp; return temp; //return set<line_no>();//书上使用这种方法,简明了许多 } } std::string TextQuery::text_line(line_no linenumber) const { return lines_of_text[linenumber]; } void TextQuery::store_file(std::ifstream &is) { string line; while (getline(is, line)) { lines_of_text.push_back(line); } } void TextQuery::build_map() { string word; map< string, set<line_no> >::iterator iter; for (line_no ix = 0; ix != lines_of_text.size(); ++ix) { istringstream stream(lines_of_text[ix]); //istringstream stream; //stream.str(lines_of_text[ix]);//有两种将string转换为istringstream的方法 while (stream >> word) { //word_map[word].insert(ix);//书上用了这种写法,只需一句简单明了多了 iter = word_map.find(word); if (iter != word_map.end()) { iter->second.insert(ix); } else { set<line_no> lineset; lineset.insert(ix); word_map.insert(make_pair(word, lineset)); } } } }
//test.cpp #include "TextQuery.h" #include <iostream> #include <string> #include <set> #include <fstream> #include <utility> using std::ifstream; using std::cerr; using std::cout; using std::cin; using std::string; using std::endl; using std::set; using std::runtime_error; ifstream& open_file(ifstream& in, const string& file) { in.close(); in.clear(); in.open(file.c_str()); return in; } void print_results(const set<TextQuery::line_no>& locs, const string& sought, const TextQuery& file) { typedef set<TextQuery::line_no> line_nums; line_nums::size_type size = locs.size(); cout << "\n" << sought << " occurs " << size << " " << "times" << endl; line_nums::const_iterator iter = locs.begin(); for ( ; iter != locs.end(); ++iter) { cout << "\t(line " << (*iter) + 1 << ") " << file.text_line(*iter) << endl; } } int main(int argc, char **argv) { /*下面两种文件的读取方式均可。运行程序有两种方法 方法一:利用cmd命令到命令行窗口,进入到可执行文件所在的目录 输入xxx.exe yyy.txt 方法二:利用vs2008属性-调试-命令参数中填写yyy.txt 然后在工作目录中填写可执行程序所在目录,将yyy.txt也放入此目录中 要注意的是对于win7系统,文件名后缀是不显示的,所以在命名文件时 不需要写yyy.txt,这样会出现文件全名变成yyy.txt.txt的情况*/ #if 0 ifstream infile; if (argc < 2 || !open_file(infile, argv[1])) { cerr << "No input file!" << endl; //return EXIT_FAILURE; } //open_file(infile, argv[1]); #endif #if 1 if (argc != 2) { throw runtime_error("wrong number of arguments"); } ifstream infile; if (!open_file(infile, argv[1])) { throw runtime_error("no input file"); } #endif TextQuery tq; tq.read_file(infile); while (true) { cout << "enter word to look for, or q to quit: "; string s; cin >> s; if (!cin || s == "q") { break; } set<TextQuery::line_no> locs = tq.run_query(s); print_results(locs, s, tq); } return 0; }
作者:DiffenYu 发表于2013-3-17 22:55:45 原文链接
阅读:58 评论:0 查看评论