c++primer文本查询程序
//两个类实现文本查询 #include <iostream> #include <memory> #include <fstream> #include <vector> #include <string> #include <set> #include <map> #include <sstream> using namespace std; class QueryResult//保存查询结果的对象 { public: string word;//查询的单词 size_t times;//出现次数 vector<string> st_all;//对应单词的所有句子 QueryResult():word(),times(0),st_all(){} }; class TextQuery { private: //ifstream in;//类成员不能是ifstream?? vector<string> txt;//按行存储文本 //set<int> row; map<string,set<int>> dict;//word 出现该word的行,从0行开始 public: //TextQuery()=default; TextQuery(ifstream &file); //void read_file(); void process_line(const string &line,size_t line_num); void process_txt(); //void print(ostream &out,) QueryResult query(string &s); }; TextQuery::TextQuery(ifstream &file) {//在构造函数中完成读取文件,和处理文件 //this->read_file(); string s; while(getline(file,s))//按行读取文件中的文本 { this->txt.push_back(s); } cout<<"read_file done!"<<endl; this->process_txt();//处理文本 //cout<<"txt size "<<this->txt.size()<<endl; } /*void TextQuery::read_file() { string s; while(getline(file,s))//按行读取文件中的文本 { this->txt.push_back(s); } cout<<"read_file done!"<<endl; }*/ void TextQuery::process_line( const string &line,size_t line_num) { istringstream row(line); string s; while(row >> s) { this->dict[s].insert(line_num); } } void TextQuery::process_txt() { for(size_t i=0;i<this->txt.size();++i) { process_line(this->txt.at(i),i);//从第0行开始处理每一行 //cout<<"line "<<i+1<<endl; } //处理完整个文档 } QueryResult TextQuery::query(string &s) { //occurs times //line num : sentence QueryResult res; res.word=s; if(!this->dict.count(s))//要查询的单词是否存在 { cout<<"query s not exist"<<endl; return res; } res.times=this->dict[s].size();//occurs times //auto word_set=this->dict[s];//查询某个单词 //for(size_t i=0;i<word_set.size();++i) for(size_t i=0;i<res.times;++i) { res.st_all.push_back(this->txt.at(i)); } //cout<<"ttt: "<<res.word<<" "<<word_set.size()<<"end"<<endl; return res; } void print(ostream &os, QueryResult res) {//输出查询结果函数 os<<res.word<<" occurs "<< res.times<<" times "<<endl; for(size_t i=0; i<res.times ;++i) { os<<"line "<<i+1<<" : "<<res.st_all.at(i)<<endl; } cout<<"print res.word: "<< res.word<<endl; } void runQueries(ifstream &infile) {//执行查询的函数 TextQuery tq(infile); string s("element");//要查询的单词 //tq.query(s); print(cout,tq.query(s)); } int main(int argc, char *argv[]) { ifstream in("666.txt"); if(!in.is_open()) { cout<<"open failed"<<endl; return 0; } runQueries(in); in.close(); return 0; }
//不使用类,使用多个函数实现 #include <iostream> #include <fstream> #include <vector> #include <string> #include <set> #include <map> #include <sstream>//istringstream using namespace std; void read_file(ifstream &in_file,vector<string> &v_file) { string s; //while(in_file >> s) while(getline(in_file,s)) { v_file.push_back(s); } } //分析每一行 void an_line(const string &line,size_t line_num,map<string,set<int>> &dict) { istringstream row(line);//文本中的一行 //line>>row; //row<<line; string word; //set<int> s1; while(row >> word) { //dict.insert({word,})//插入对应的单词和行号 dict[word].insert(line_num); } } int main(int argc, char *argv[]) { //read_file ifstream in("666.txt"); if(!in.is_open()) { cout<<"open failed"<<endl; return 0; } vector<string> file; read_file(in,file); map<string,set<int>> dict;//string 每个单词, set<int> 出现该单词的行数,按升序 //for(vector<string>::const_iterator it=file.cbegin();it!=file.cend();++it) for(size_t i=0;i<file.size();++i) {//对每行进行操作 an_line(file.at(i),i+1,dict); } auto res=dict["element"];//查询单词element cout<<"element occurs "<<res.size()<<" times "<<endl; for(auto it:res)//输出行号,即对应行的内容 { cout<<"line "<<it<<" : "<<file.at(it-1)<<endl;//行号从1开始,vector从0开始 }
in.close(); return 0; }
//使用shared_ptr #include <iostream> #include <map> #include <sstream>//istringstream #include <string> #include <vector> #include <fstream> #include <set> #include <memory> using namespace std; using line_no=std::vector<std::string>::size_type; class QueryResult; class TextQuery { private: shared_ptr<vector<string>> file; map<string,shared_ptr<set<line_no>>> wm; public: TextQuery(ifstream &in); //void QueryResult query(const std::string &) const ; }; TextQuery::TextQuery(ifstream &in):file(new vector<string>) { string line; while(getline(in,line)) { file->push_back(line); size_t n=file->size()-1;//获得行号 istringstream row(line); string s; while(row >> s) { shared_ptr<set<line_no>> &lines=wm[s];//需要加取地址符号 //auto &lines=wm[s]; //if(wm->find(s)==wm.end()) //{ // wm[s]=new set<line_no>; //} if(!lines)//如果Lines为空 { lines.reset(new set<line_no>);//分配一个新的set } lines->insert(n);//插入行号 } } } class QueryResult//在使用该类具体成员之前定义该类 { friend void print(ostream &os,const QueryResult& res); private: string word; shared_ptr<set<line_no>> hang; shared_ptr<vector<string>> file; public: QueryResult(const string &s,shared_ptr<set<line_no>> l ,shared_ptr<vector<string>> f):word(s),hang(l),file(f){} }; QueryResult TextQuery::query( const string & s) const { static shared_ptr<set<line_no>> nodata(new set<line_no>); /*if(wm.find(s) == wm.end()) { cout<<"s not exist"<<endl; }*/ map<string,shared_ptr<set<line_no>>>::const_iterator loc = wm.find(s);//返回的是const迭代器 //auto loc=wm.find(s); if(loc == wm.end()) { return QueryResult(s,nodata,this->file); } else { return QueryResult(s,loc->second,this->file);//loc为迭代器,第二个参数为动态set } } void print(ostream &os,const QueryResult& res) { os<<res.word<<" occurs " << res.hang->size() <<" times "<<endl; for(auto it:*(res.hang))// { //os<<"line "<<i+1<<" : "<<res->file->at(i)<<endl; os<<"line "<<it+1<<" : "<<res.file->at(it)<<endl; } } void runQueries(ifstream &infile) {//执行查询的函数 TextQuery tq(infile); string s("element");//要查询的单词 //tq.query(s); print(cout,tq.query(s)); } int main(int argc, char *argv[]) { ifstream in("666.txt"); if(!in.is_open()) { cout<<"open failed"<<endl; return 0; } runQueries(in); in.close(); return 0; }