重写TextQuery和QueryResult类,用StrBlob代替vector<string>保存输入文件:
我为StrBlobPtr重载了一个deref成员函数:
string& StrBlobPtr::deref(int num) const
{
std::shared_ptr<vector<string>> p = check(curr + num, "dereference past end!");
return (*p)[curr + num];
}
头文件:
#ifndef HEAD_H
#define HEAD_H
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <fstream>
#include <sstream>
#include <set>
#include <initializer_list>
#include <memory>
using std::cout;
using std::cin;
using std::endl;
using std::ends;
using std::string;
using std::vector;
using std::map;
using std::set;
#endif
StrBlob类:
#ifndef STRBLOB_H
#define STRBLOB_H
#include "Head.h"
#include "Head.h"
#include "StrBlobPtr.h"
class Strblob
{
friend class StrBlobPtr;
/*friend StrBlobPtr::StrBlobPtr(Strblob &a, size_t i);
friend std::shared_ptr<vector<string>> StrBlobPtr::check(size_t, const string&) const;*/
public:
typedef vector<string>::size_type size_type;
Strblob();
Strblob(std::initializer_list<string> li);
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(string val) { data->push_back(val); }
void pop_back();
const string& back() const;
string& back();
const string& front() const;
string& front();
StrBlobPtr begin();
StrBlobPtr end();
private:
std::shared_ptr<vector<string>> data;
void check(const size_type&, const string&) const;
};
#endif
#include "Strblob.h"
#include "StrBlobPtr.h"
Strblob::Strblob() : data(std::make_shared<vector<string>>()) {}
Strblob::Strblob(std::initializer_list<string> il) :
data(std::make_shared<vector<string>>(il)) {}
void Strblob::pop_back()
{
check(0, "Strblob is empty!");
data->pop_back();
}
string& Strblob::front()
{
check(0, "Strblob is empty!");
return data->front();
}
const string& Strblob::front() const
{
check(0, "Strblob is empty!");
return data->front();
}
string& Strblob::back()
{
check(0, "Strblob is empty!");
return data->back();
}
const string& Strblob::back() const
{
check(0, "Strblob is empty!");
return data->back();
}
void Strblob::check(const size_type &i, const string &msg) const
{
if (i < data->size())
throw std::out_of_range(msg);
}
StrBlobPtr Strblob::begin()
{
return StrBlobPtr(*this);
}
StrBlobPtr Strblob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
StrBlobPtr类:
#ifndef StrBlobPtr_h
#define StrBlobPtr_h
#include "Head.h"
class Strblob;
class StrBlobPtr
{
public:
StrBlobPtr();
StrBlobPtr(Strblob &a, size_t i = 0);
StrBlobPtr(const Strblob &a, size_t sz = 0);
string& deref() const;
string& deref(int) const;
StrBlobPtr& incr();
private:
std::shared_ptr<vector<string>> check(size_t, const string&) const;
std::shared_ptr<vector<string>> check2(size_t, const string&) const;
std::weak_ptr<vector<string>> wptr;//保存一个weak_ptr。
std::weak_ptr<vector<string>> wptrr;
std::size_t curr;//当前位置
};
#endif
#include "Strblob.h"
#include "StrBlobPtr.h"
StrBlobPtr::StrBlobPtr() : curr(0) {}
StrBlobPtr::StrBlobPtr(Strblob &a, size_t i) :
wptr(a.data), curr(i) {}
StrBlobPtr::StrBlobPtr(const Strblob &a, size_t sz) : wptrr(a.data), curr(sz) {}
std::shared_ptr<vector<string>> StrBlobPtr::check(size_t sz, const string &msg) const
{
auto p = wptr.lock();
if (!p)
{
p = check2(sz, msg);
if (p) return p;
throw std::runtime_error(msg);
}
else if (sz >= p->size())
throw std::out_of_range(msg);
return p;
}
string& StrBlobPtr::deref() const
{
std::shared_ptr<vector<string>> p = check(curr, "dereference past end!");
return (*p)[curr];
}
string& StrBlobPtr::deref(int num) const
{
std::shared_ptr<vector<string>> p = check(curr + num, "dereference past end!");
return (*p)[curr + num];
}
StrBlobPtr& StrBlobPtr::incr()
{
auto p = check(curr, "increment past end of StrBlobPtr!");
++curr;
return *this;
}
std::shared_ptr<vector<string>> StrBlobPtr::check2(size_t sz, const string &msg) const
{
auto p = wptrr.lock();
if (!p)
throw std::runtime_error(msg);
else if (sz >= p->size())
throw std::out_of_range(msg);
return p;
}
TextQuery类:
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include "Head.h"
#include "Strblob.h"
class QueryResult;
class TextQuery
{
public:
TextQuery() = default;
TextQuery(const std::initializer_list<std::string> &il) :ifile(il) {}
TextQuery(std::ifstream &);
QueryResult query(const std::string &) const;
private:
Strblob ifile;
std::map<std::string, std::shared_ptr<set<size_t>>> iresult;
};
#endif
#include "TextQuery.h"
#include "QueryResult.h"
TextQuery::TextQuery(std::ifstream &is)
{
//以文本流的形式构造vector
std::string s;
while (getline(is, s))
{
ifile.push_back(s);//没有为ifile分配内存
int n = ifile.size() - 1;
std::istringstream iss;
iss.str(s);
string word;
while (iss >> word)
{
auto &p = iresult[word];
if (!p)
iresult[word].reset(new set<size_t>);
iresult[word]->insert(n);
iresult[word]->insert(n);
}
}
}
QueryResult TextQuery::query(const std::string &ele) const
{
std::shared_ptr<set<size_t>> p(new set<size_t>);
auto iter = iresult.find(ele);
if (iter == iresult.end())
return QueryResult(ele, ifile, p);
else
return QueryResult(ele, ifile, iter->second);
}
StrBlobPtr类:
#include "TextQuery.h"
#include "QueryResult.h"
TextQuery::TextQuery(std::ifstream &is)
{
//以文本流的形式构造vector
std::string s;
while (getline(is, s))
{
ifile.push_back(s);//没有为ifile分配内存
int n = ifile.size() - 1;
std::istringstream iss;
iss.str(s);
string word;
while (iss >> word)
{
auto &p = iresult[word];
if (!p)
iresult[word].reset(new set<size_t>);
iresult[word]->insert(n);
iresult[word]->insert(n);
}
}
}
QueryResult TextQuery::query(const std::string &ele) const
{
std::shared_ptr<set<size_t>> p(new set<size_t>);
auto iter = iresult.find(ele);
if (iter == iresult.end())
return QueryResult(ele, ifile, p);
else
return QueryResult(ele, ifile, iter->second);
}
#include "Strblob.h"
#include "StrBlobPtr.h"
StrBlobPtr::StrBlobPtr() : curr(0) {}
StrBlobPtr::StrBlobPtr(Strblob &a, size_t i) :
wptr(a.data), curr(i) {}
StrBlobPtr::StrBlobPtr(const Strblob &a, size_t sz) : wptrr(a.data), curr(sz) {}
std::shared_ptr<vector<string>> StrBlobPtr::check(size_t sz, const string &msg) const
{
auto p = wptr.lock();
if (!p)
{
p = check2(sz, msg);
if (p) return p;
throw std::runtime_error(msg);
}
else if (sz >= p->size())
throw std::out_of_range(msg);
return p;
}
string& StrBlobPtr::deref() const
{
std::shared_ptr<vector<string>> p = check(curr, "dereference past end!");
return (*p)[curr];
}
string& StrBlobPtr::deref(int num) const
{
std::shared_ptr<vector<string>> p = check(curr + num, "dereference past end!");
return (*p)[curr + num];
}
StrBlobPtr& StrBlobPtr::incr()
{
auto p = check(curr, "increment past end of StrBlobPtr!");
++curr;
return *this;
}
std::shared_ptr<vector<string>> StrBlobPtr::check2(size_t sz, const string &msg) const
{
auto p = wptrr.lock();
if (!p)
throw std::runtime_error(msg);
else if (sz >= p->size())
throw std::out_of_range(msg);
return p;
}
runQueries函数
#include "Head.h"
#include "TextQuery.h"
#include "QueryResult.h"
void runQueries(std::ifstream &inifile)
{
TextQuery tq(inifile);
while (true)
{
cout << "enter word to look for,or q to quit: " << endl;
std::string s;
if (!(cin >> s) || s == "q")
break;
print(cout, tq.query(s)) << endl;
}
}
主函数:
#include "Head.h"
void runQueries(std::ifstream &inifile);
int main()
{
std::ifstream is("f://gao.txt");
runQueries(is);
return 0;
}