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

C++ Primer文本查询程序(TextQuery)的实现(2014.5.24)

2014-07-01 09:52 856 查看
    详见书的10.6节。
     按行查找文件,并且按照顺序进行显示,同时对单词出现的次数进行统计。同一行出现多次,只按照一次进行计算。
1.头文件
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <cstdlib>
using namespace std;
2.TextQuery类的实现,该类定义了读文件的接口,在读取文件的时候先行将每一个单词和行进行关联。文件采用vector容器进行存储。
class TextQuery{
public:
 typedef vector<string>::size_type line_no;//是一种别名,类型
 void read_file(ifstream &is)
 {
  store_file(is);//读入并保存文件
  build_map();//创建关联单词和行号的map容器
 }
 set<line_no> run_query(const string&) const;
 string text_line(line_no) const;//行文本
private:
 void store_file(ifstream&);
 void build_map();
 vector<string> lines_of_text;//文件行存储
 map<string,set<line_no>> word_map;//关联容器,单词和文本记录关联
};
3.文件读取函数
void TextQuery::store_file(ifstream &is)
{
 string textline;
 while (getline(is,textline))
  lines_of_text.push_back(textline);
}
4.将单词和行进行关联
void TextQuery::build_map()//将读入的单词和行号进行关联
{
 for(line_no line_num=0;line_num!=lines_of_text.size();++line_num){
  istringstream line(lines_of_text[line_num]);
  string word;
  while(line>>word)
   word_map[word].insert(line_num);
 }
}

5.
set<TextQuery::line_no>//执行查询函数

TextQuery::run_query(const string &query_word) const
{
 map<string,set<line_no>>::const_iterator
  loc=word_map.find(query_word);
 if(loc==word_map.end())
  return set<line_no>();//没有找到,返回空的set集合
 else
  return loc->second;//找到,当返回行
}
string TextQuery::text_line(line_no line) const//同时还需要返回行
{
 if(line < lines_of_text.size())
  return lines_of_text[line];
 throw out_of_range("line number out of range");
}
string make_plural(size_t ctr,const string &word,const string &ending)//当计数器不为一的时候,返回单词的复数版本
{
 return (ctr==1) ? word: word+ending;
}

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<<" "<<make_plural(size,"time","s")<<endl;
 line_nums::const_iterator it =locs.begin();
 for(;it!=locs.end();++it){
  cout<<"\t(line"<<(*it)+1<<")"<<file.text_line(*it)<<endl;
 }
}
ifstream& open_file(ifstream &in,const string &file)//文件读取函数
{
 in.close();
 in.clear();
 in.open(file.c_str());
 return in;
}
int main() //主函数
{
 ifstream infile;
 string filename="D:\\Users\\shiwei\\Desktop\\test.txt";
 /*if(argc<2||!open_file(infile,argv[1])){
  cerr<<"No input file!"<<endl;
  return EXIT_FAILURE;
 }*/
 if(!open_file(infile,filename)){
  cerr<<"No input file!"<<endl;
  //return EXIT_FAILURE;
  return 1;
 }
 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);//输出结果
 }
 system("pause");
 return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++