习题12.2:
头文件:
#ifndef STRBLOB_H
#define STRBLOB_H
#include <vector>
#include <string>
#include <memory>
#include <initializer_list>
#include <stdexcept>
class StrBlob
{
public:
using size_type = std::vector<std::string>::size_type;
StrBlob();
StrBlob(std::initializer_list<std::string> 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<std::vector<std::string>> data;
};
//类外定义构造函数
StrBlob::StrBlob() :data(std::make_shared<std::vector<std::string>>()){ };
StrBlob::StrBlob(std::initializer_list<std::string> s)
:data(std::make_shared<std::vector<std::string>>(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
习题12.6:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <utility>
#include "StrBlob.h"
using std::cin; using std::cout; using std::endl;
using std::vector; using std::string;
using std::istream; using std::ifstream;
using std::map; using std::set; using std::pair;
vector<int> *ret()
{
return new vector<int>;
}
vector<int> *read(vector<int> *pv)
{
int i = 0;
while (cin >> i)
pv->push_back(i);
return pv;
}
void print(vector<int> *pv)
{
for (auto i : *pv)
cout << i << " ";
cout << endl;
}
int main()
{
auto pv = ret();
read(pv);
print(pv);
delete pv;
getchar();
return 0;
}
习题12.7:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <utility>
#include <memory>
#include "StrBlob.h"
using std::cin; using std::cout; using std::endl;
using std::vector; using std::string;
using std::istream; using std::ifstream;
using std::map; using std::set; using std::pair;
using Ptr = std::shared_ptr<vector<int>>;
auto ret()->Ptr
{
return std::make_shared<vector<int>>();
}
auto read(Ptr pv)->Ptr
{
int i = 0;
while (cin >> i)
pv->push_back(i);
return pv;
}
void print(Ptr pv)
{
for (auto i : *pv)
cout << i << " ";
cout << endl;
}
int main()
{
print(read(ret()));
getchar();
return 0;
}
习题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 <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include <utility>
#include <memory>
using std::cin; using std::cout; using std::endl;
using std::vector; using std::string;
using std::istream; using std::ifstream;
using std::map; using std::set; using std::pair;
using std::allocator;
int main()
{
std::size_t n = 7;
allocator<string> alloc;
auto const p = alloc.allocate(n);
auto q = p;
string s;
while (cin >> s && q != p + n)
alloc.construct(q++, s);
//use of it
while (q != p)
{
cout << *--q << endl;
alloc.destroy(q);
}
alloc.deallocate(p,n);
getchar();
return 0;
}
习题12.30:
Query.h
#ifndef QUERY_H
#define QUERY_H
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <memory>
#include <map>
#include <set>
class QueryResult;
class TextQuery
{
public:
using line_no = std::vector<std::string>::size_type;
TextQuery(std::ifstream &);
QueryResult query(const std::string &)const;
private:
std::shared_ptr<std::vector<std::string>> file;
std::map<std::string, std::shared_ptr<std::set<line_no>>> wm;
};
class QueryResult
{
friend std::ostream &print(std::ostream &is, const QueryResult &qr);
public:
using line_no = std::vector<std::string>::size_type;
QueryResult(std::string s,
std::shared_ptr<std::set<line_no>> l, std::shared_ptr<std::vector<std::string>> f)
:sought(s), lines(l), file(f){ };
private:
std::string sought;
std::shared_ptr<std::set<line_no>> lines;
std::shared_ptr<std::vector<std::string>> file;
};
#endif
Query.cpp
#include "Query.h"
TextQuery::TextQuery(std::ifstream &ifs) :file(new std::vector<std::string>)
{
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<line_no>);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const std::string &sought)const
{
static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>);
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;
}