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;
}

 

posted @ 2022-03-20 16:07  菠萝超级酸  阅读(119)  评论(0编辑  收藏  举报