码迷,mamicode.com
首页 > 编程语言 > 详细

C++primer 容器的综合应用:文本查询程序

时间:2017-12-17 12:21:02      阅读:254      评论:0      收藏:0      [点我收藏+]

标签:技术   一个   getline   amp   while   复数   bre   span   技术分享   

  1 #include<iostream>
  2 #include<string>
  3 #include<fstream>
  4 #include<sstream>
  5 #include<vector>
  6 #include<map>
  7 #include<set>
  8 
  9 using namespace::std;
 10 /*要完成简单的单词查询任务,首先需要创建一个类TextQuery来帮我们完成这个任务,在这个类中private中
 11 内部调用的对象和函数,在public中创建read_file将文件读入保存在vector中并关联每个单词和行号的map容器
 12 通过run_query函数查找string并返回包含单词出现的每一个行号的set对象利用text_line输出每一行*/
 13 class TextQuery{
 14 public:
 15      typedef vector<string>::size_type  line_no;
 16      void read_file(ifstream &is)     //该函数每次从文件中读入一行,并将它保存在容器vector中
 17          //,输入完毕后,将创建关联的每个单词和行号的map容器
 18      {store_file(is);build_map();    }
 19      set<line_no> run_query(const string&) const; //其形参为string类型的对象,返回一个set对象,该对象包含该string对象的所有行的行号
 20      string text_line(line_no) const;//其形参是一个行号,返回输入文本中该行号对应的文本行
 21 
 22 
 23 private:
 24     void store_file(ifstream &is);
 25     void build_map();
 26     vector<string> lines_of_text;
 27     map<string,set<line_no> > word_map;
 28 };
 29 
 30 /*将之前输入进来的infile.txt的每行内容读到一个vector<string>对象中,包括.*/
 31 void TextQuery::store_file(ifstream &is)
 32 {
 33     string textline;
 34     while(getline(is,textline))
 35         lines_of_text.push_back(textline);  //store 由于是在public中因此可以访问private 的对象
 36     //cout<<lines_of_text[0];
 37 
 38 }
 39 /*利用istringstream 将每一行中的文本忽略空格输入到一个map容器中,word_map[word]代表的是set<line_no>对象
 40 然后调用set的insert函数在set对象中添加当前的行号。如果某一个单词在同一行中反复出现,则不做任何操作*/
 41 void TextQuery::build_map()
 42 {
 43     for(line_no line_num=0;line_num!=lines_of_text.size();++line_num )
 44     {
 45         istringstream line(lines_of_text[line_num]);
 46         string word;
 47     while(line>>word)
 48         word_map[word].insert(line_num);
 49 
 50     }
 51 }
 52 /*run_query函数带有const string 类型对象的引用参数,并以这个参数作为下标来访问word_map对象。
 53 如果找到了就返回一个对应的set(其中包含所有出现的行号),否则就返回一个空的set*/
 54 set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const
 55 {
 56     map<string,set<line_no>>::const_iterator
 57         loc=word_map.find(query_word);
 58     if(loc==word_map.end())
 59         return set<line_no>();
 60     else
 61         return loc->second;
 62 
 63 }
 64 /*运行run_query后,将获得一组所查找的单词出现的行号。除了要输出该单词出现的次数之外,
 65 还要输出该单词所在的每一行。就是通过之前的vector<string> 来输出*/
 66 string TextQuery::text_line(line_no line) const
 67 {
 68     if(line<lines_of_text.size())
 69         return lines_of_text[line];
 70     throw out_of_range("line number out of range");
 71 }
 72 /*用来读取一个文件*/
 73 ifstream &open_file(ifstream &in,const string &file)
 74 {
 75     in.close();//close in case it was already open
 76     in.clear();//clear any exiting errors;
 77     in.open(file.c_str());//open the file we were given
 78     return in;
 79 }
 80 /*如果输出的次数大于1那么就输出复数*/
 81 string make_plural(size_t ctr,const string &word,const string &ending)
 82 {
 83     return (ctr==1)?word:word+ending;
 84 }
 85 /*首先输出出现的次数、调用了make_plural函数,之后输出每一个出现的行号,并且调用text_line来输出每一行*/
 86 void print_result(const set<TextQuery::line_no>&locs,const string &sought,const TextQuery &file)
 87 {
 88     typedef set<TextQuery::line_no> line_nums;
 89     line_nums::size_type size=locs.size();
 90     cout<<"\n"<<sought<<" occurs "<<size<<" "
 91         <<make_plural(size,"time","s")<<endl;
 92     line_nums::const_iterator it=locs.begin();
 93     for(;it!=locs.end();++it)
 94     {
 95             cout<<"\t(line"
 96                 <<(*it)+1<<")"
 97                 <<file.text_line(*it)<<endl;
 98     }
 99 
100 
101 }
102 
103 
104 /*创建一个TextQuery对象实现简单的用户查询会话。如果需要查询,那么就调用run_query函数,返回单词
105 出现的行的集合,并且调用print_result函数来输出函数*/
106 int main(int argc,char**argv)
107 {
108     ifstream infile;
109     if(!open_file(infile,"infile.txt"))
110     throw runtime_error("no remove file");
111     TextQuery tq;
112     tq.read_file(infile);
113     while(true)
114     {
115         cout<<"enter word to look for ,or q to quit: ";
116         string s;
117         cin>>s;
118         if(!cin||s=="q")  break;
119         set<TextQuery::line_no> locs=tq.run_query(s);
120         print_result(locs,s,tq);
121     
122     }
123     return 0;
124 }
infile.txt 中的内容
With some (indeed, many) C compilers, 
you can get away with some whats called a common 
definition of a variable too.
some some some i 

技术分享图片

C++primer 容器的综合应用:文本查询程序

标签:技术   一个   getline   amp   while   复数   bre   span   技术分享   

原文地址:http://www.cnblogs.com/lovecodepql/p/8051589.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!