练习12.2
#include <iostream>
#include <memory>
#include <vector>
using std::cout;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::shared_ptr;
using std::string;
using std::vector;
using size_type = vector<string>::size_type;
class StrBlob
{
private:
shared_ptr<vector<string>> data;
void check(size_type i, const std::string &msg) const;
public:
StrBlob();
StrBlob(initializer_list<string> il);
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const string &t) { data->push_back(t); }
void pop_back();
string &front();
string &back();
const string &front() const;
const string &back() const;
};
StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
void StrBlob::check(size_type i, const string &msg) const
{
if (i >= data->size())
throw out_of_range(msg);
}
string &StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const string &StrBlob::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
string &StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const string &StrBlob::back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
}
int main()
{
StrBlob b1;
StrBlob b2 = {"a", "an", "the"};
b1 = b2;
b2.push_back("about");
cout << "size of b1: " << b1.size() << "\nsize of b1: " << b2.size() << "\n";
return 0;
}
练习12.6
#include <iostream>
#include <vector>
#include <memory>
using std::cin;
using std::cout;
using std::vector;
vector<int> *creat_vector(void)
{
return new vector<int>;
}
void read_to_vector(vector<int> *pv)
{
int num = 0;
while (cin >> num)
{
pv->push_back(num);
}
}
void print_vector(const vector<int> *pv)
{
for (const auto &num : *pv)
cout << num << "\t";
cout << "\n";
}
int main()
{
vector<int> *pv = creat_vector();
read_to_vector(pv);
print_vector(pv);
return 0;
delete pv;
return 0;
}
练习12.7
#include <iostream>
#include <vector>
#include <memory>
using std::cin;
using std::cout;
using std::make_shared;
using std::shared_ptr;
using std::vector;
shared_ptr<vector<int>> creat_vector(void)
{
return make_shared<vector<int>>();
}
void read_to_vector(shared_ptr<vector<int>> pv)
{
int num = 0;
while (cin >> num)
{
pv->push_back(num);
}
}
void print_vector(const shared_ptr<vector<int>> pv)
{
for (const auto &num : *pv)
cout << num << "\t";
cout << "\n";
}
int main()
{
shared_ptr<vector<int>> pv = creat_vector();
read_to_vector(pv);
print_vector(pv);
return 0;
}
练习12.14
#include <memory>
#include <iostream>
using std::cout;
using std::shared_ptr;
using std::string;
struct destination
{
string infodes;
};
using connection = struct Connection
{
string infocon;
} *;
connection connect(destination *p)
{
connection q = new Connection;
return q;
};
void disconnect(connection q) { delete q; }
void end_connection(connection *p) { disconnect(*p); }
void f(destination &d)
{
connection c = connect(&d);
shared_ptr<connection> p(&c, end_connection);
}
int main()
{
destination d;
f(d);
return 0;
}
练习12.15
#include <memory>
#include <iostream>
using std::cout;
using std::shared_ptr;
using std::string;
struct destination
{
string infodes;
};
using connection = struct Connection
{
string infocon;
} *;
connection connect(destination *p)
{
connection q = new Connection;
return q;
};
void disconnect(connection q) { delete q; }
void f(destination &d)
{
connection c = connect(&d);
shared_ptr<connection> p(&c, [](connection *q)
{ disconnect(*q); });
}
int main()
{
destination d;
f(d);
return 0;
}
练习12.16
#include <memory>
using std::unique_ptr;
int main()
{
unique_ptr<int> ut;
auto pt = ut;
ut = pt;
return 0;
}
练习12.19
#include <iostream>
#include <memory>
#include <vector>
using std::cout;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;
using size_type = vector<string>::size_type;
class StrBlobPtr;
class StrBlob
{
private:
shared_ptr<vector<string>> data;
void check(size_type i, const std::string &msg) const;
public:
friend class StrBlobPtr;
StrBlob();
StrBlob(initializer_list<string> il);
StrBlobPtr begin();
StrBlobPtr end();
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const string &t) { data->push_back(t); }
void pop_back();
string &front();
string &back();
const string &front() const;
const string &back() const;
};
class StrBlobPtr
{
private:
shared_ptr<vector<string>> check(size_t, const string &) const;
weak_ptr<vector<string>> wptr;
size_t curr;
public:
StrBlobPtr() : curr(0) {}
StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
string &deref() const;
StrBlobPtr &incr();
};
StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
void StrBlob::check(size_type i, const string &msg) const
{
if (i >= data->size())
throw out_of_range(msg);
}
string &StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const string &StrBlob::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
string &StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const string &StrBlob::back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
}
shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const
{
auto ret = wptr.lock();
if (!ret)
throw runtime_error("unbound StrBlobPtr");
if (i >= ret->size())
throw out_of_range(msg);
return ret;
}
string &StrBlobPtr::deref() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
StrBlobPtr &StrBlobPtr::incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr StrBlob::begin()
{
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
int main()
{
StrBlob b1 = {"a", "an", "the"};
StrBlobPtr sbp(b1, 0);
cout << sbp.deref() << "\t" << sbp.incr().deref() << "\n";
return 0;
}
练习12.20
#include <iostream>
#include <memory>
#include <vector>
#include <fstream>
using std::cerr;
using std::cout;
using std::getline;
using std::ifstream;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;
using size_type = vector<string>::size_type;
class StrBlobPtr;
class StrBlob
{
private:
shared_ptr<vector<string>> data;
void check(size_type i, const std::string &msg) const;
public:
friend class StrBlobPtr;
StrBlob();
StrBlob(initializer_list<string> il);
StrBlobPtr begin();
StrBlobPtr end();
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const string &t) { data->push_back(t); }
void pop_back();
string &front();
string &back();
const string &front() const;
const string &back() const;
};
class StrBlobPtr
{
private:
shared_ptr<vector<string>> check(size_t, const string &) const;
weak_ptr<vector<string>> wptr;
size_t curr;
public:
StrBlobPtr() : curr(0) {}
StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
string &deref() const;
StrBlobPtr &incr();
};
StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
void StrBlob::check(size_type i, const string &msg) const
{
if (i >= data->size())
throw out_of_range(msg);
}
string &StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const string &StrBlob::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
string &StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const string &StrBlob::back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
}
shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const
{
auto ret = wptr.lock();
if (!ret)
throw runtime_error("unbound StrBlobPtr");
if (i >= ret->size())
throw out_of_range(msg);
return ret;
}
string &StrBlobPtr::deref() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
StrBlobPtr &StrBlobPtr::incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr StrBlob::begin()
{
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
int main()
{
ifstream inf("cplusplus//multiple//exercise12_20//txt//in_file.txt");
if (!inf)
{
cerr << "文件打开失败!\n";
return -1;
}
string str;
StrBlob inb;
StrBlobPtr inbp(inb, 0);
while (getline(inf, str))
inb.push_back(str);
for (size_t i = 0; i != inb.size(); inbp.incr(), ++i)
cout << inbp.deref() << "\n";
return 0;
}
练习12.22
#include <iostream>
#include <memory>
#include <vector>
using std::cout;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;
using size_type = vector<string>::size_type;
class ConstStrBlobPtr;
class StrBlob
{
private:
shared_ptr<vector<string>> data;
void check(size_type i, const std::string &msg) const;
public:
friend class ConstStrBlobPtr;
StrBlob();
StrBlob(initializer_list<string> il);
ConstStrBlobPtr begin();
ConstStrBlobPtr end();
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const string &t) { data->push_back(t); }
void pop_back();
string &front();
string &back();
const string &front() const;
const string &back() const;
};
class ConstStrBlobPtr
{
private:
shared_ptr<vector<string>> check(size_t, const string &) const;
weak_ptr<vector<string>> wptr;
size_t curr;
public:
ConstStrBlobPtr() : curr(0) {}
ConstStrBlobPtr(const StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
string &deref() const;
ConstStrBlobPtr &incr();
};
StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
void StrBlob::check(size_type i, const string &msg) const
{
if (i >= data->size())
throw out_of_range(msg);
}
string &StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const string &StrBlob::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
string &StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const string &StrBlob::back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
}
shared_ptr<vector<string>> ConstStrBlobPtr::check(size_t i, const string &msg) const
{
auto ret = wptr.lock();
if (!ret)
throw runtime_error("unbound StrBlobPtr");
if (i >= ret->size())
throw out_of_range(msg);
return ret;
}
string &ConstStrBlobPtr::deref() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
ConstStrBlobPtr &ConstStrBlobPtr::incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
ConstStrBlobPtr StrBlob::begin()
{
return ConstStrBlobPtr(*this);
}
ConstStrBlobPtr StrBlob::end()
{
auto ret = ConstStrBlobPtr(*this, data->size());
return ret;
}
int main()
{
const StrBlob b1 = {"a", "an", "the"};
ConstStrBlobPtr sbp(b1, 0);
cout << sbp.deref() << "\t" << sbp.incr().deref() << "\n";
return 0;
}
练习12.23
#include <iostream>
using std::cout;
int main()
{
const char *strp1 = "qwertyuiop", *strp2 = "1234567890";
char *p = new char[20];
size_t i = 0;
for (i = 0; i != 10; ++i)
p[i] = strp1[i];
for (size_t j = 0; j != 10; ++j, ++i)
p[i] = strp2[j];
cout << p;
delete[] p;
return 0;
}
#include <iostream>
using std::cout;
using std::string;
int main()
{
string strp1 = "qwertyuiop", strp2 = "1234567890";
char *p = new char[20];
strp1 += strp2;
for (size_t i = 0; i != 20; ++i)
p[i] = strp1[i];
cout << p;
delete[] p;
return 0;
}
练习12.24
#include <iostream>
using std::cin;
using std::cout;
using std::string;
int main()
{
string str;
char *p = new char[10];
cin >> str;
if (str.size() > 10)
{
delete[] p;
p = new char[str.size()];
}
for (size_t i = 0; i != str.size(); ++i)
p[i] = str[i];
for (size_t i = 0; i != str.size(); ++i)
cout << p[i];
cout << "\n";
delete[] p;
return 0;
}
练习12.26
#include <iostream>
using std::allocator;
using std::cin;
using std::cout;
using std::string;
int main()
{
size_t n = 10;
allocator<string> a;
auto p = a.allocate(n);
string s;
string *q = p;
while (cin >> s && q != p + n)
a.construct(q++, s);
const size_t size = q - p;
q -= size;
for (size_t i = 0; i != size; ++i)
cout << q[i] << "\n";
while (q != p + size)
a.destroy(q++);
a.deallocate(p, n);
return 0;
}
练习12.27
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_
#include <vector>
#include <set>
#include <sstream>
using std::ifstream;
using std::istringstream;
using std::set;
using std::vector;
class TextQuery
{
public:
TextQuery() = default;
TextQuery(ifstream &infile);
map<size_t, string> query(const string word);
vector<string> text;
map<string, set<size_t>> word_line;
};
TextQuery::TextQuery(ifstream &infile)
{
string line_text;
while (getline(infile, line_text))
text.push_back(line_text);
string text_word;
for (size_t i = 0; i != text.size(); ++i)
{
istringstream word_in(text[i]);
while (word_in >> text_word)
{
bool wordExist = false;
for (auto &wl : word_line)
if (wl.first == text_word)
{
wl.second.insert(i);
wordExist = true;
break;
}
if (!wordExist)
{
set<size_t> si;
si.insert(i);
word_line[text_word] = si;
}
}
}
}
map<size_t, string> TextQuery::query(const string word)
{
map<size_t, string> line_str;
for (const auto &w : word_line)
{
if (w.first == word)
{
auto wbg = w.second.begin();
for (size_t i = 0; i != w.second.size(); ++i, ++wbg)
line_str[*wbg + 1] = text[*wbg];
}
}
return line_str;
}
#endif
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_
#include <iostream>
#include <map>
using std::map;
using std::ostream;
using std::string;
class QueryResult
{
public:
QueryResult() = default;
void print(ostream &out, map<size_t, string> pss);
};
void QueryResult::print(ostream &out, map<size_t, string> pss)
{
out << "该元素出现了" << pss.size() << "次\n";
for (auto &ss : pss)
out << "(行 " << ss.first << ")" << ss.second + "\n";
}
#endif
#include <fstream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"
using std::cerr;
using std::cin;
using std::cout;
void runQueries(ifstream &infile)
{
TextQuery tq(infile);
QueryResult qr;
while (true)
{
cout << "输入查找的单词,或按“q”退出:";
string s;
if (!(cin >> s) || s == "q")
break;
qr.print(cout, tq.query(s));
}
}
int main()
{
ifstream infile("exercise12_27/txt/infile.txt");
if (!infile)
{
cerr << "文件打开失败!\n";
return -1;
}
runQueries(infile);
return 0;
}
练习12.28
#include <fstream>
#include <vector>
#include <sstream>
#include <map>
#include <set>
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;
using std::ostream;
using std::set;
using std::string;
using std::vector;
vector<string> vline;
map<string, set<size_t>> word_line;
void process_text(ifstream &infile)
{
string line, word;
while (getline(infile, line))
vline.push_back(line);
for (size_t i = 0; i != vline.size(); ++i)
{
istringstream inw(vline[i]);
while (inw >> word)
{
bool wordExist = false;
for (auto &wl : word_line)
if (wl.first == word)
{
wl.second.insert(i);
wordExist = true;
break;
}
if (!wordExist)
{
set<size_t> si;
si.insert(i);
word_line[word] = si;
}
}
}
}
map<size_t, string> query(const string word)
{
map<size_t, string> line_str;
for (auto &wl : word_line)
if (wl.first == word)
{
auto wbg = wl.second.begin();
for (size_t i = 0; i != wl.second.size(); ++i, ++wbg)
line_str[*wbg + 1] = vline[*wbg];
}
return line_str;
}
void print(ostream &out, map<size_t, string> pss)
{
out << "该元素出现了" << pss.size() << "次\n";
for (auto &ss : pss)
out << "(行 " << ss.first << ")" << ss.second + "\n";
}
int main()
{
ifstream infile("exercise12_28\\txt\\infile.txt");
if (!infile)
{
cerr << "文件打开失败!\n";
return -1;
}
process_text(infile);
while (true)
{
cout << "输入查找的单词,或按“q”退出:";
string s;
if (!(cin >> s) || s == "q")
break;
print(cout, query(s));
}
return 0;
}
练习12.29
#include <fstream>
#include <vector>
#include <sstream>
#include <map>
#include <set>
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;
using std::ostream;
using std::set;
using std::string;
using std::vector;
vector<string> vline;
map<string, set<size_t>> word_line;
void process_text(ifstream &infile)
{
string line, word;
while (getline(infile, line))
vline.push_back(line);
for (size_t i = 0; i != vline.size(); ++i)
{
istringstream inw(vline[i]);
while (inw >> word)
{
bool wordExist = false;
for (auto &wl : word_line)
if (wl.first == word)
{
wl.second.insert(i);
wordExist = true;
break;
}
if (!wordExist)
{
set<size_t> si;
si.insert(i);
word_line[word] = si;
}
}
}
}
map<size_t, string> query(const string word)
{
map<size_t, string> line_str;
for (auto &wl : word_line)
if (wl.first == word)
{
auto wbg = wl.second.begin();
for (size_t i = 0; i != wl.second.size(); ++i, ++wbg)
line_str[*wbg + 1] = vline[*wbg];
}
return line_str;
}
void print(ostream &out, map<size_t, string> pss)
{
out << "该元素出现了" << pss.size() << "次\n";
for (auto &ss : pss)
out << "(行 " << ss.first << ")" << ss.second + "\n";
}
int main()
{
ifstream infile("exercise12_29\\txt\\infile.txt");
if (!infile)
{
cerr << "文件打开失败!\n";
return -1;
}
process_text(infile);
do
{
cout << "输入查找的单词,或按“q”退出:";
string s;
if (!(cin >> s) || s == "q")
break;
print(cout, query(s));
} while (true);
return 0;
}
练习12.30
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_
#include "QueryResult.hpp"
#include <map>
#include <sstream>
using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;
class TextQuery
{
public:
TextQuery(ifstream &);
QueryResult query(string &) const;
private:
shared_ptr<vector<string>> file;
map<string, shared_ptr<set<line_no>>> wm;
};
TextQuery::TextQuery(ifstream &is) : file(new vector<string>)
{
string text;
while (getline(is, text))
{
file->push_back(text);
int n = file->size() - 1;
istringstream line(text);
string word;
while (line >> word)
{
auto &lines = wm[word];
if (!lines)
lines.reset(new set<line_no>);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(string &sought) const
{
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto loc = wm.find(sought);
if (loc == wm.end())
return QueryResult(sought, nodata, file);
else
return QueryResult(sought, loc->second, file);
}
#endif
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_
#include <memory>
#include <set>
#include <vector>
using std::endl;
using std::ostream;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;
using line_no = vector<string>::size_type;
class QueryResult
{
friend ostream &print(ostream &, const QueryResult &);
public:
QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f) : sought(s), lines(p), file(f) {}
private:
string sought;
shared_ptr<set<line_no>> lines;
shared_ptr<vector<string>> file;
};
string make_plural(size_t ctr, const string &ending, const string &word = "s")
{
return (ctr > 1) ? word + ending : word;
}
ostream &print(ostream &os, const QueryResult &qr)
{
os << qr.sought << " occurc " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
for (auto num : *qr.lines)
os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) << endl;
return os;
}
#endif
#include <fstream>
#include <iostream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"
using std::cerr;
using std::cin;
using std::cout;
void runQueries(ifstream &infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to look for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q")
break;
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream infile("exercise12_30\\txt\\infile.txt");
if (!infile)
{
cerr << "Open file error!\n";
return -1;
}
runQueries(infile);
return 0;
}
练习12.32
#ifndef STRBLOB_HPP_
#define STRBLOB_HPP_
#include <iostream>
#include <memory>
#include <vector>
#include <fstream>
using std::cerr;
using std::cout;
using std::getline;
using std::ifstream;
using std::initializer_list;
using std::make_shared;
using std::out_of_range;
using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::vector;
using std::weak_ptr;
using size_type = vector<string>::size_type;
class StrBlobPtr;
class StrBlob
{
private:
shared_ptr<vector<string>> data;
void check(size_type i, const std::string &msg) const;
public:
friend class StrBlobPtr;
StrBlob();
StrBlob(initializer_list<string> il);
StrBlobPtr begin();
StrBlobPtr end();
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
void push_back(const string &t) { data->push_back(t); }
void pop_back();
string &front();
string &back();
const string &front() const;
const string &back() const;
};
class StrBlobPtr
{
private:
shared_ptr<vector<string>> check(size_t, const string &) const;
weak_ptr<vector<string>> wptr;
size_t curr;
public:
StrBlobPtr() : curr(0) {}
StrBlobPtr(StrBlob &a, size_t sz = 0) : wptr(a.data), curr(sz) {}
string &deref() const;
StrBlobPtr &incr();
};
StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}
StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
void StrBlob::check(size_type i, const string &msg) const
{
if (i >= data->size())
throw out_of_range(msg);
}
string &StrBlob::front()
{
check(0, "front on empty StrBlob");
return data->front();
}
const string &StrBlob::front() const
{
check(0, "front on empty StrBlob");
return data->front();
}
string &StrBlob::back()
{
check(0, "back on empty StrBlob");
return data->back();
}
const string &StrBlob::back() const
{
check(0, "back on empty StrBlob");
return data->back();
}
void StrBlob::pop_back()
{
check(0, "pop_back on empty StrBlob");
}
shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string &msg) const
{
auto ret = wptr.lock();
if (!ret)
throw runtime_error("unbound StrBlobPtr");
if (i >= ret->size())
throw out_of_range(msg);
return ret;
}
string &StrBlobPtr::deref() const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
StrBlobPtr &StrBlobPtr::incr()
{
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}
StrBlobPtr StrBlob::begin()
{
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
#endif
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_
#include "QueryResult.hpp"
#include <map>
#include <sstream>
#include "strBlob.hpp"
using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;
class TextQuery
{
public:
TextQuery(ifstream &);
QueryResult query(string &) const;
private:
StrBlob file;
map<string, shared_ptr<set<line_no>>> wm;
};
TextQuery::TextQuery(ifstream &is)
{
string text;
while (getline(is, text))
{
file.push_back(text);
int n = file.size() - 1;
istringstream line(text);
string word;
while (line >> word)
{
auto &lines = wm[word];
if (!lines)
lines.reset(new set<line_no>);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(string &sought) const
{
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto loc = wm.find(sought);
if (loc == wm.end())
return QueryResult(sought, nodata, file);
else
return QueryResult(sought, loc->second, file);
}
#endif
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_
#include <memory>
#include <set>
#include <vector>
#include "strBlob.hpp"
using std::endl;
using std::ostream;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;
using line_no = vector<string>::size_type;
class QueryResult
{
friend ostream &print(ostream &, const QueryResult &);
public:
QueryResult(string s, shared_ptr<set<line_no>> p, StrBlob f) : sought(s), lines(p), file(f) {}
private:
string sought;
shared_ptr<set<line_no>> lines;
StrBlob file;
};
string make_plural(size_t ctr, const string &ending, const string &word = "s")
{
return (ctr > 1) ? word + ending : word;
}
ostream &print(ostream &os, const QueryResult &qr)
{
os << qr.sought << " occurc " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
auto qrfile = qr.file;
for (auto num : *qr.lines)
{
StrBlobPtr inbp(qrfile, 0);
auto temp = num;
while (temp-- != 0)
inbp.incr();
os << "\t(line " << num + 1 << ") " << inbp.deref() << endl;
}
return os;
}
#endif
#include <fstream>
#include <iostream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"
using std::cerr;
using std::cin;
using std::cout;
void runQueries(ifstream &infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to look for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q")
break;
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream infile("exercise12_32\\txt\\infile.txt");
if (!infile)
{
cerr << "Open file error!\n";
return -1;
}
runQueries(infile);
return 0;
}
练习12.33
#ifndef TEXTQUERY_HPP_
#define TEXTQUERY_HPP_
#include "QueryResult.hpp"
#include <map>
#include <sstream>
using std::getline;
using std::ifstream;
using std::istringstream;
using std::map;
class TextQuery
{
public:
TextQuery(ifstream &);
QueryResult query(string &) const;
private:
shared_ptr<vector<string>> file;
map<string, shared_ptr<set<line_no>>> wm;
};
TextQuery::TextQuery(ifstream &is) : file(new vector<string>)
{
string text;
while (getline(is, text))
{
file->push_back(text);
int n = file->size() - 1;
istringstream line(text);
string word;
while (line >> word)
{
auto &lines = wm[word];
if (!lines)
lines.reset(new set<line_no>);
lines->insert(n);
}
}
}
QueryResult TextQuery::query(string &sought) const
{
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto loc = wm.find(sought);
if (loc == wm.end())
return QueryResult(sought, nodata, file);
else
return QueryResult(sought, loc->second, file);
}
#endif
#ifndef QUERYRESULT_HPP_
#define QUERYRESULT_HPP_
#include <memory>
#include <set>
#include <vector>
using std::endl;
using std::ostream;
using std::set;
using std::shared_ptr;
using std::string;
using std::vector;
using line_no = vector<string>::size_type;
class QueryResult
{
friend ostream &print(ostream &, const QueryResult &);
public:
QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f) : sought(s), lines(p), file(f) {}
set<line_no>::iterator begin() const;
set<line_no>::iterator end() const;
shared_ptr<vector<string>> get_file() const;
private:
string sought;
shared_ptr<set<line_no>> lines;
shared_ptr<vector<string>> file;
};
set<line_no>::iterator QueryResult::begin() const
{
return this->lines->begin();
}
set<line_no>::iterator QueryResult::end() const
{
return this->lines->end();
}
shared_ptr<vector<string>> QueryResult::get_file() const
{
return this->file;
}
string make_plural(size_t ctr, const string &ending, const string &word = "s")
{
return (ctr > 1) ? word + ending : word;
}
ostream &print(ostream &os, const QueryResult &qr)
{
os << qr.sought << " occurc " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
for (auto num = qr.begin(); num != qr.end(); ++num)
os << "\t(line " << *num + 1 << ") " << *(qr.file->begin() + *num) << endl;
return os;
}
#endif
#include <fstream>
#include <iostream>
#include "QueryResult.hpp"
#include "TextQuery.hpp"
using std::cerr;
using std::cin;
using std::cout;
void runQueries(ifstream &infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to look for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q")
break;
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream infile("exercise12_33\\txt\\infile.txt");
if (!infile)
{
cerr << "Open file error!\n";
return -1;
}
runQueries(infile);
return 0;
}
|