//两个类实现文本查询
#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;
}