习题12.2:
头文件:
#ifndef STRBLOB_H
#define STRBLOB_H
#include
#include
#include
#include
#include
class StrBlob
{
public:
using size_type = std::vector::size_type;
StrBlob();
StrBlob(std::initializer_list s);
size_type size()const{ return data->size(); }
bool empty()const{ return data->empty(); }
//添加&删除元素
void push_back(const std::string &t){ data->push_back(t); }
void pop_back();//需要检查还是否有元素,若为空则抛出异常
//元素访问
std::string &front();
std::string &back();
const std::string &front()const;//overload version
const std::string &back()const;
private://github上学的,成员函数与数据成员分开
void check(size_type i, const std::string &msg)const;//包括异常处理
private:
std::shared_ptr> data;
};
//类外定义构造函数
StrBlob::StrBlob() :data(std::make_shared>()){ };
StrBlob::StrBlob(std::initializer_list s)
:data(std::make_shared>(s)){ };
void StrBlob::check(size_type i, const std::string &msg)const
{
if (i >= data->size())
throw std::out_of_range(msg);
}
std::string &StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const std::string &StrBlob::front()const
{
check(0, "front on empty StrBlob");
return data->front();
}
std::string &StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const std::string &StrBlob::back()const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
习题12.20:
int main()
{
ifstream infile("有标点单词段落测试.txt");
StrBlob str;
for (string s; std::getline(infile, s); str.push_back(s));
StrBlobPtr str_ptr(str);
for (auto i = 0; i != str.size() && cout << str_ptr.deref() << endl; str_ptr.incr())++i;
getchar();
return 0;
}
习题12.26:
#include
#include
#include
#include
#include
习题12.30:
Query.h
#ifndef QUERY_H
#define QUERY_H
#include
#include
#include
#include
#include
#include
#include
#include
Query.cpp
#include "Query.h"
TextQuery::TextQuery(std::ifstream &ifs) :file(new std::vector)
{
for (std::string line_text; std::getline(ifs,line_text); line_text.clear())
{ //外层循环处理行,内层处理单词及行数set
//std::cout << line_text << std::endl;
file->push_back(line_text); //将该行内容压入容器
int n = file->size() - 1; //记录当前行号
std::istringstream iss(line_text);
for (std::string word_raw,word_new; iss >> word_raw; word_new.clear())
{
std::remove_copy_if(word_raw.begin(), word_raw.end(), std::back_inserter(word_new), ispunct);
auto &lines = wm[word_new];//获取指向set的shared_ptr,用引用可避免引用计数增加
if (!lines)
lines.reset(new std::set);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const std::string &sought)const
{
static std::shared_ptr> nodata(new std::set);
auto loc = wm.find(sought);
if (loc == wm.end())
return QueryResult(sought, nodata, file);
else
return QueryResult(sought, loc->second, file);
}
std::string make_plural(std::size_t n, const std::string &s1, const std::string &s2)
{
return n <= 1 ? s1 : s1 + s2;
}
std::ostream &print(std::ostream &os, const QueryResult &qr)
{
os << "element occurs " << qr.lines->size()
<< make_plural(qr.lines->size(), "time", "s") << std::endl;
for (auto l : *(qr.lines))
os << "\t(line " << l + 1 << ") "
<< *(qr.file->begin() + l) << std::endl;
return os;
}
main.cpp
#include "Query.h"
void runQuery(std::ifstream &infile)
{
TextQuery tq(infile);
while (true)
{
std::cout << "enter word to look for, or q to quit:";
std::string s;
if (!(std::cin >> s) || s == "q")break;
print(std::cout, tq.query(s));
}
}
int main()
{
std::ifstream infile("184.txt");
runQuery(infile);
getchar();
return 0;
}