#ifndef _TEXTQUERY_H
#define _TEXTQUERY_H
#include <vector>
#include <string>
#include <set>
#include <map>
#include <fstream>
#include <sstream>
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;
};
void TextQuery::store_file(std::ifstream &is)
{
std::string textline;
while(getline(is,textline))
{
lines_of_text.push_back(textline);
}
}
void TextQuery::build_map()
{
for(line_no line_num=0;line_num!=lines_of_text.size();++line_num)
{
std::istringstream line(lines_of_text[line_num]);
std::string word;
while(line>>word)
{
int index1=word.find(",");
int index2=word.find(".");
int index=index1>index2 ? index1 : index2;
if(index!=-1)
{
word_map[word.substr(0,index)].insert(line_num);
}
else
{
word_map[word].insert(line_num);
}
}
}
}
std::set<TextQuery::line_no> TextQuery::run_query(const std::string& query_word) const
{
std::map<std::string,std::set<line_no>>::const_iterator loc=word_map.find(query_word);
if(loc==word_map.end())
{
return std::set<line_no>();
}
else
{
return loc->second;
}
}
std::string TextQuery::text_line(line_no line) const
{
if(line<lines_of_text.size())
{
return lines_of_text[line];
}
else
{
throw std::out_of_range("line number out of range");
}
}
#endif
// test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <set>
#include "TextQuery.h"
void print_results(const std::set<TextQuery::line_no>& locs, const std::string& sought,const TextQuery& file);
#define FN "cjc.txt"
int main(int argc,char **argv)
{
std::ifstream infile(FN,std::ios::in);
if(!infile)
{
std::cerr<<"No input file!"<<std::endl;
return EXIT_FAILURE;
}
TextQuery tq;
tq.read_file(infile);
while(true)
{
std::cout<<"enter word to look for, or q to quit:";
std::string s;
std::cin>>s;
std::cin.get();
if(!std::cin || s=="q")
{
break;
}
std::set<TextQuery::line_no> locs=tq.run_query(s);
print_results(locs,s,tq);
}
system("pause");
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////
std::string make_plural(int size,std::string str1,std::string str2)
{
if(size>1)
{
return str1+str2;
}
else
{
return str1;
}
}
void print_results(const std::set<TextQuery::line_no>& locs, const std::string& sought,const TextQuery& file)
{
typedef std::set<TextQuery::line_no> line_nums;
line_nums::size_type size=locs.size();
std::cout<<sought<<" occurs "<<size<<" "
<<make_plural(size, "time","s")<<std::endl;
line_nums::const_iterator it=locs.begin();
for(;it!=locs.end();++it)
{
std::cout<<"\t(line "
<<(*it)+1<<") "
<<file.text_line(*it)<<std::endl;
}
std::cout<<"**********************************************"<<std::endl;
}
<<c++ primer>>文本查询程序