C++Primer TextQuery完整代码

  1. TextQuery.h
#ifndef TEXTQUERY_H
#define TEXTQUERY_H

#include <memory>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <iostream>
using std::cout;
//读入并解析文件,将解析结果存入QueryResult对象中

class QueryResult;

class TextQuery
{
    using _line_no = std::vector<std::string>::size_type;

    public:
    //根据输入文件流将代查询文件按行存储到vector中并使用shared_ptr进行托管;建立每个单词和所在行数的对应关系,同样使用shared_ptr进行资源托管
        TextQuery(std::ifstream&);
        //根据单词和所在行的对应关系返回查询结果对象
        QueryResult query(const std::string&)const;


    private:
//使用shred_ptr减少数据间进行复制次数,整个程序只有一份vector<string>存储查询文件;只有一份单词对应行数set<_lie_no>的存储
         //将每一行作为vector的一个元素进行存储
        std::shared_ptr<std::vector<std::string>>_file;
        //存储每个单词和对应的行号
        std::map<std::string,
                std::shared_ptr<std::set<_line_no>>>_wm;
        static std::string cleanup_str(const std::string &);
};

#endif // TEXTQUERY_H

  1. QueryResult.h
#ifndef QUERYRESULT_H
#define QUERYRESULT_H
#include <string>
#include <set>
#include <vector>
#include <memory>

using std::vector;
using std::set;
using std::string;
using std::shared_ptr;


class QueryResult
{

    public:
        using _lineno = std::vector<std::string>::size_type;

        QueryResult(const string &sought,
                    const shared_ptr<vector<string>>&file,
                     const shared_ptr<set<_lineno>>&lines)
                    :_sought(sought)
                    ,_file(file)
                    ,_lines(lines)
                    {
                    };

        set<_lineno>::size_type size(){return _lines->size();}
//重载输出流函数输出QueryResult对象
        friend std::ostream& operator<<(std::ostream&,const QueryResult&);

    private:
        std::string _sought;
        std::shared_ptr<std::vector<std::string>> _file;
        std::shared_ptr<std::set<_lineno>> _lines;
};

#endif 
  1. TextQuery.cpp
#include "TextQuery.h"
#include "QueryResult.h"
#include "make_pluarl.h"
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>

using std::string;
using std::vector;
using std::set;
using std::shared_ptr;
using std::endl;


TextQuery::TextQuery(std::ifstream& file)
:_file(new std::vector<std::string>()){
    std::string line_text;
    int line_no;
    //std::istringstream line;
    std::string word;
    while(std::getline(file,line_text)){

            _file->push_back(line_text);
            line_no = _file->size()-1;
            std::istringstream line(line_text);//初始化
            while(line>>word){
                word = cleanup_str(word);
                auto& no = _wm[word];
                if(!no)
                    no.reset(new std::set<_line_no>);
                no->insert(line_no);
            }
    }

}

QueryResult TextQuery::query(const std::string& sought)const{
    static shared_ptr<set<_line_no>> nodata(new set<_line_no>);
    auto it = _wm.find(cleanup_str(sought));
    if(it==_wm.end()){
        //查找的单词不存在
        return QueryResult(sought,_file,nodata);
    }else{
        //找到查找单词
        return QueryResult(sought,_file,it->second);
    }

}

std::string TextQuery::cleanup_str(const std::string&word){

    string ret;

    for(auto it = word.begin();it!=word.end();++it){
        if(!ispunct(*it))
            ret += tolower(*it);
    }

    return ret;
}


std::ostream & operator<<(std::ostream& os,const QueryResult& qr){
    os<<qr._sought<<" occur "<<qr._lines->size()<<" "
    <<make_pluarl(qr._lines->size(),"line","s")<<"\n";
    for(auto num : *qr._lines){
        os<<"\t(line: "<<num+1<<"): "
          <<*(qr._file->begin()+num)<<endl;
    }


    return os;
}

  1. make_pluarl.h
//判断函数是否为复数,如果是复数就加‘s’
#ifndef MAKE_PLUARL_H_INCLUDED
#define MAKE_PLUARL_H_INCLUDED
#include <string>
//判断行数是不是复数
inline
std::string make_pluarl(size_t ctr, std::string word,std::string ending ){
    return (ctr==1)? word : word+ ending;
}


#endif 
  1. main.cpp
#include "TextQuery.h"
#include "QueryResult.h"
#include "make_pluarl.h"
#include <fstream>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
int main()
{
    string filename ="./test.txt";
    std::ifstream inputfile(filename);
    TextQuery text(inputfile);
    while(true){
        cout << "Enter word to look for, or q to quit: ";
        string sought;
        if(!(std::cin>>sought)||sought=="q")
            break;
        cout<<text.query(sought)<<endl;
    }
    return 0;
}

所求结果为查询单词所在的行数而不是所出现的次数。
没有使用书中的print函数打印QueryResult对象,重载operator<<函数进行打印。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值