C++实践之路----容器的综合运用

来源:互联网 发布:淘宝买家内衣秀大尺度 编辑:程序博客网 时间:2024/06/05 20:03

阅读C++ Primer第十章

需求:

文本查询程序需要提供的功能:

(1)提供查询功能,能够根据用户输入的单词,查询到所在的行

(2)根据行号,返回对应行的文本

(3)根据用户输入的文件名,读入文件

         这是对外的的3个功能。然后现在抽象下名字

Text_Query

{

         Set<line_no>query(word);

         Stringtext_line(line_no)

         Voidread_file(file_name)

}

         主要数据结构分析:

         1.这里单词和行号的对应关系可以使用map记录map<word,set<line_no>>

         2.文本的记录可以使用vector<string>记录

         分析下函数的具体功能:

Void read_file(file_name)

{

         //1. 读入并保存文件

         Store_file(file_name);

         //2. 建立map
         build_map();

}

         其中Store_file和build_map是内部函数,分别用来存储行和对单词进行统计。

         此时根据上面的分析就可以给出实现代码了。

#include <iostream>#include <string>#include <vector>#include <map>#include <set>#include <fstream>#include <sstream>using namespace std;class Text_Query{public:typedef std::vector<std::string>::size_type line_no;public:Text_Query(){std::cout << "Create Text_Query\n";}void read_file( std::ifstream &ifs );const std::set<line_no> query(std::string&);string text_line( line_no no) const { return lines_of_word[no];}private:void store_file( std::ifstream &ifs );void build_map();std::string cleanup_str( std::string );std::vector<std::string> lines_of_word;std::map<std::string,std::set<line_no>> words_map;};std::ifstream& open_file( std::ifstream &is, std::string file_name ){is.open(file_name,std::ios_base::in);return is;}void Text_Query::read_file( std::ifstream &ifs ){store_file(ifs);build_map();}void Text_Query::store_file( std::ifstream &ifs ){std::string line;while ( getline(ifs,line) )lines_of_word.push_back(line);}void Text_Query::build_map(){for ( line_no no = 0; no < lines_of_word.size(); ++no ){std::istringstream line( lines_of_word[no] );std::string word;while ( line >> word )words_map[cleanup_str(word)].insert(no);}}std::string Text_Query::cleanup_str( std::string word ){std::string ret;for ( std::string::const_iterator itor=word.begin(); itor != word.end(); ++itor ){if ( !ispunct(*itor) )ret += tolower(*itor);}return ret;}const std::set<Text_Query::line_no> Text_Query::query( std::string& word ){std::map<std::string,std::set<Text_Query::line_no> >::const_iterator it = words_map.find(cleanup_str(word));if ( it != words_map.end() )return it->second;return std::set<Text_Query::line_no>();}void print_results(const set<Text_Query::line_no>& locs, const string& sought, const Text_Query &file){// if the word was found, then print count and all occurrencestypedef set<Text_Query::line_no> line_nums; line_nums::size_type size = locs.size();cout << "\n" << sought << " occurs "<< size << " "<< "times" << endl;// print each line in which the word appearedline_nums::const_iterator it = locs.begin();for ( ; it != locs.end(); ++it) {cout << "\t(line "// don't confound user with text lines starting at 0<< (*it) + 1 << ") "<< file.text_line(*it) << endl;}}int main( int argc, char *argv[] ){std::ifstream infile;// 1.判断输入参数是否正确if ( argc != 2 || !open_file(infile, argv[1]) ){std::cerr << "No input file!\n";return -1;}// 2.创建Text_Query对象Text_Query 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;// 3.读入查询的单词set<Text_Query::line_no> locs = tq.query(s);// 4.输出行号和文本内容print_results(locs, s, tq);}return 0;}


原创粉丝点击