c++ primer 第十二章习题
程序员文章站
2024-03-21 14:36:46
...
练习12.1 都是4个
练习12.2
#ifndef MYSTRBLOB_H
#define MYSTRBLOB_H
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
class StrBlob {
friend class StrBlobPtr;
public:
typedef std::vector<std::string>::size_type size_type;
// constructors
StrBlob() : data(std::make_shared<std::vector<std::string>>()) { }
StrBlob(std::initializer_list<std::string> il);
// size operations
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
// add and remove elements
void push_back(const std::string &t) { data->push_back(t); }
void pop_back();
// element access
std::string& front();
std::string& back();
std::string& front() const;
std::string& back() const;
private:
std::shared_ptr<std::vector<std::string>> data;
// throws msg if data[i] isn't valid
void check(size_type i, const std::string &msg) const;
};
StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)){}
void StrBlob::pop_back() {
check(0,"pop_back on empty StrBlob");
data->pop_back();
}
void StrBlob::check(size_type i, const std::string& msg)const {
if (i >= data->size())
throw std::out_of_range(msg);
}
std::string& StrBlob::back() {
check(0,"back on empty StrBlob");
return data->back();
}
std::string& StrBlob::front() {
check(0, "front on empty StrBlob");
return data->front();
}
std::string& StrBlob::back() const{
check(0,"back on empty StrBlob");
return data->back();
}
std::string& StrBlob::front() const{
check(0, "front on empty StrBlob");
return data->front();
}
#endif
练习12.3 不需要 对象内容改变不需要对象是const类型。
练习12.4 i是size_type无符号型整数
练习12.5 优点:可以隐式转换,可以赋值构造 缺点:在不需要转换的地方可能自动转换。
练习12.6
void input(vector<int>* p) {
int k;
while(cin>>k)
p->push_back(k);
}
void output(vector<int>* p) {
for(auto k: *p)
cout << k << ' ';
}
int main(int argc, char const *argv[])
{
vector<int>* p1 = new vector<int>;
input(p1);
output(p1);
delete(p1);
return 0;
}
练习12.7
void input(shared_ptr<vector<int>> p) {
int k;
while(cin>>k)
p->push_back(k);
}
void output(shared_ptr<vector<int>> p) {
for(auto k: *p)
cout << k << ' ';
}
int main(int argc, char const *argv[])
{
shared_ptr<vector<int>> p1 = make_shared<vector<int>>();
input(p1);
output(p1);
return 0;
}
练习12.8 没有
练习12.9 line 2: r内存泄漏 line 4: r2指向q2指向的内存,原r2收回。
练习12.10 正确
练习12.11 p指向的内存被删除但还有可能使用p
练习12.12 a 合法 b 不合法 不能赋值内置指针给共享指针 c不合法,同b d合法
练习12.13 sp失效
练习12.15
void f(destination &d) {
connection c = connect(&d);
shared_ptr<connection> p(&c, [](connection*p) {disconnect(p);});
}
练习12.17 (a) 非法,将整数赋值智能指针 (b) 非法,将非动态内存赋值 (c)合法 (d) 同b (e)合法 (f)合法但可能使用无效p2
练习12.18 unique_ptr只能独享动态变量,因此改变所有权的时候需要release,而共享指针指向的对象由多个指针指向,不需要release。
练习12.19
#ifndef MYSTRBLOB_H
#define MYSTRBLOB_H
#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>
using namespace std;
class StrBlobPtr;
class StrBlob {
friend class StrBlobPtr;
friend class ConstStrBlobPtr;
public:
typedef vector<string>::size_type size_type;
// constructors
StrBlob() : data(make_shared<vector<string>>()) { }
StrBlob(initializer_list<string> il);
// size operations
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
// add and remove elements
void push_back(const string &t) { data->push_back(t); }
void pop_back();
// element access
string& front();
string& back();
string& front() const;
string& back() const;
StrBlobPtr begin();
StrBlobPtr end();
ConstStrBlobPtr cbegin() const;
ConstStrBlobPtr cend() const;
private:
shared_ptr<vector<string>> data;
// throws msg if data[i] isn't valid
void check(size_type i, const string &msg) const;
};
StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)){}
void StrBlob::pop_back() {
check(0,"pop_back on empty StrBlob");
data->pop_back();
}
void StrBlob::check(size_type i, const string& msg)const {
if (i >= data->size())
throw out_of_range(msg);
}
string& StrBlob::back() {
check(0,"back on empty StrBlob");
return data->back();
}
string& StrBlob::front() {
check(0, "front on empty StrBlob");
return data->front();
}
string& StrBlob::back() const{
check(0,"back on empty StrBlob");
return data->back();
}
string& StrBlob::front() const{
check(0, "front on empty StrBlob");
return data->front();
}
class StrBlobPtr
{
public:
StrBlobPtr():curr(0){}
StrBlobPtr(StrBlob& a, size_t sz = 0): wptr(a.data), curr(sz){}
string& deref() const;
StrBlobPtr& incr();
private:
weak_ptr<vector<string>> wptr;
size_t curr;
shared_ptr<vector<string>> check(size_t index, const string& msg) const;
};
inline StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this);}
inline StrBlobPtr StrBlob::end() {
return StrBlobPtr(*this, data->size());
}
string& StrBlobPtr::deref() const {
auto p = check(curr, "out of range");
return (*p)[curr];
}
StrBlobPtr& StrBlobPtr::incr() {
check(curr, "increment past end of StrBlobPtr");
curr++;
return *this;
}
shared_ptr<vector<string>> StrBlobPtr::check(size_t index, const string& msg) const {
auto p = wptr.lock();
if(!p)
throw runtime_error("unbound StrBlobPtr");
else if (curr >= p->size())
throw runtime_error(msg);
else
return p;
}
练习12.20
int main(int argc, char const *argv[])
{
StrBlob sb;
string s;
while(cin>>s)
sb.push_back(s);
StrBlobPtr sbp = sb.begin();
int n = sb.size();
while(n--) {
cout << sbp.deref()<<endl;
sbp.incr();
}
return 0;
}
练习12.21 前一个,更清晰。
练习12.22
class ConstStrBlobPtr
{
public:
ConstStrBlobPtr():curr(0){}
ConstStrBlobPtr(const StrBlob& a, size_t sz = 0): wptr(a.data), curr(sz){}
string& deref() const;
ConstStrBlobPtr& incr();
private:
weak_ptr<vector<string>> wptr;
size_t curr;
shared_ptr<vector<string>> check(size_t index, const string& msg) const;
};
inline ConstStrBlobPtr StrBlob::cbegin() const{ return ConstStrBlobPtr(*this);}
inline ConstStrBlobPtr StrBlob::cend() const{
return ConstStrBlobPtr(*this, data->size());
}
string& ConstStrBlobPtr::deref() const {
auto p = check(curr, "out of range");
return (*p)[curr];
}
练习12.23
char* concat(const char* a, const char* b) {
char* p = new char[strlen(a)+strlen(b)];
int i = 0;
for(; i < strlen(a); i++)
p[i] = a[i];
for(int j = 0; j <= strlen(b); j++)
p[i+j] = b[j];
return p;
}
int main(int argc, char const *argv[])
{
auto p = concat("hello ", "world");
for(int i = 0; i < strlen(p); i++)
cout << p[i];
cout << endl;
return 0;
}
string concat(const char* a, const char* b) {
string a1 = a, b1 = b;
return a1+b1;
}
int main(int argc, char const *argv[])
{
auto p = concat("hello ", "world");
cout << p <<endl;
return 0;
}
练习12.24
char* input() {
char c;
char* p = new char[10];
int i = 0, size = 10;
while(cin>>c) {
p[i] = c;
i++;
if (i >= size) {
size *= 2;
char* tmp = new char[size];
for(int j = 0; j < i; j++)
tmp[j] = p[j];
delete [] p;
p = tmp;
}
}
p[i] = '\0';
return p;
}
int main(int argc, char const *argv[])
{
string p = input();
cout << p<<endl;
return 0;
}
练习12.25 delete[] pa;
练习12.26
int main(int argc, char const *argv[])
{
allocator<string> alloc;
int size = 10;
auto beg = alloc.allocate(size);
auto cur = beg;
string s;
while(cin >> s && cur - beg < size) {
alloc.construct(cur++,s);
}
while(cur != beg){
cout << *--cur << endl;
alloc.destroy(cur);
}
alloc.deallocate(beg, size);
}
练习12.27
class QueryResult;
class TextQuery{
friend class QueryResult;
vector<string>* text;
unordered_map<string, set<int>> lines;
public:
TextQuery(ifstream& input) {
text = new vector<string>();
string s;
int line = 0;
while(getline(input,s)) {
text->push_back(s);
string tmp;
istringstream inw(s);
while(inw >> tmp)
lines[tmp].insert(line);
line++;
}
}
QueryResult query(string s);
};
class QueryResult
{
friend ostream& print(ostream& os, QueryResult q);
set<int> l;
vector<string>* text;
public:
QueryResult(TextQuery& t, string& s) {
l = t.lines[s];
text = t.text;
};
};
QueryResult TextQuery::query(string s) {
return QueryResult(*this, s);
}
ostream& print(ostream& os, QueryResult q){
if(q.l.size() == 0)
os << "word not found"<<endl;
else
for(auto i : q.l)
cout << "(line "<< i<<") "<<(*q.text)[i]<<endl;
return os;
}
练习12.28
int main(int argc, char const *argv[])
{
vector<string> text;
ifstream infile(argv[1]);
string s;
unordered_map<string,set<int>> lines;
int line = 0;
while(getline(infile, s)) {
text.push_back(s);
string tmp;
istringstream ssin(s);
while(ssin >> tmp)
lines[tmp].insert(line);
line++;
}
while(true) {
cout << "please input the word you want to query or input q to quit:";
if(!(cin >> s) || s == "q")
break;
auto res = lines[s];
if(res.size() == 0)
cout << "word "<< s<<" not found!"<<endl;
else
for(auto i : res)
cout << "(line "<< i << ") "<< text[i]<<endl;
}
return 0;
}
练习12.29
void runQueries(ifstream& infile) {
TextQuery tq(infile);
do{
cout << "enter the word to look for, or q to quit: ";
string s;
if (!(cin>>s) || s=="q")break;
print(cout, tq.query(s)) << endl;
}while(true);
}
练习12.30
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <unordered_map>
#include <cstring>
#include <exception>
#include <memory>
#include <fstream>
#include <sstream>
#include "MyStrBlob.h"
using namespace std;
class QueryResult;
class TextQuery{
shared_ptr<vector<string>> text;
unordered_map<string, shared_ptr<set<int>>> lines;
public:
TextQuery(ifstream& input) {
text = make_shared<vector<string>>();
string s;
int line = 0;
while(getline(input,s)) {
text->push_back(s);
string tmp;
istringstream inw(s);
while(inw >> tmp) {
auto& p = lines[tmp];
if(!p)
p.reset(new set<int>);
p->insert(line);
}
line++;
}
}
QueryResult query(string& s);
};
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& q);
shared_ptr<set<int>> l;
shared_ptr<vector<string>> text;
string word;
public:
QueryResult(string& s, shared_ptr<set<int>> lines ,shared_ptr<vector<string>> t) {
l = lines;
word = s;
text = t;
};
};
QueryResult TextQuery::query(string& s) {
auto p = lines.find(s);
if(p == lines.end())
return QueryResult(s, make_shared<set<int>>(), text);
else {
cout << p->second->size()<<endl;
return QueryResult(s, p->second, text);
}
}
ostream& print(ostream& os, const QueryResult& q){
if(q.l->size() == 0)
os << "word "<<q.word<<" not found"<<endl;
else
for(auto i : (*q.l))
cout << "(line "<< i<<") "<< (*q.text)[i]<<endl;
return os;
}
void runQueries(ifstream& infile) {
TextQuery tq(infile);
do{
cout << "enter the word to look for, or q to quit: ";
string s;
if (!(cin>>s) || s=="q")break;
print(cout, tq.query(s)) << endl;
}while(true);
}
int main(int argc, char const *argv[])
{
vector<string> text;
ifstream infile(argv[1]);
runQueries(infile);
return 0;
}
练习12.31 set好,自动去重排序。
练习12.32
class TextQuery{
StrBlob text;
unordered_map<string, shared_ptr<set<int>>> lines;
public:
TextQuery(ifstream& input) {
string s;
int line = 0;
while(getline(input,s)) {
text.push_back(s);
string tmp;
istringstream inw(s);
while(inw >> tmp) {
auto& p = lines[tmp];
if(!p)
p.reset(new set<int>);
p->insert(line);
}
line++;
}
}
QueryResult query(string& s);
};
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& q);
shared_ptr<set<int>> l;
StrBlob text;
string word;
public:
QueryResult(string& s, shared_ptr<set<int>> lines , StrBlob t) {
l = lines;
word = s;
text = t;
};
};
ostream& print(ostream& os, const QueryResult& q){
if(q.l->size() == 0)
os << "word "<<q.word<<" not found"<<endl;
else
for(auto i : (*q.l)){
ConstStrBlobPtr ptr(q.text,i);
cout << "(line "<< i<<") "<< ptr.deref()<<endl;
}
return os;
}
练习12.33
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& q);
shared_ptr<set<int>> l;
shared_ptr<vector<string>> text;
string word;
public:
QueryResult(string& s, shared_ptr<set<int>> lines ,shared_ptr<vector<string>> t) {
l = lines;
word = s;
text = t;
};
set<int>::iterator begin(){return l->begin();};
set<int>::iterator end(){return l->end();}
shared_ptr<vector<string>> get_file(){return text;};
};
上一篇: JAVA生成PDF文件(根据模板和html 显示中文)
下一篇: JAVA 生成CSV文件