12.2:
#include<iostream>
using namespace std;
#include<vector>
class StrBlob
{
public:
using size_type = vector<string>::size_type;
StrBlob() :data(make_shared<vector<string>>()) {};
StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il)) {};
size_type size() { return data->size(); }
bool empty()const { return data->empty(); }
void push_back(const string& s) { data->push_back(s); }
void pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
string& front()
{
check(0, "front on empty StrBlob");
return data->front();
}
string& back()
{
check(0, "front on empty StrBlob");
return data->back();
}
const string& front()const
{
check(0, "front on empty StrBlob");
return data->front();
}
const string& back()const
{
check(0, "front on empty StrBlob");
return data->back();
}
private:
shared_ptr<vector<string>>data;
void check(size_type i, const string& msg)const
{
if (i >= data->size())
{
throw out_of_range(msg);
}
}
};
int main()
{
const StrBlob csb{ "hello", "world", "pezy" };
StrBlob sb{ "hello", "world", "Mooophy" };
cout << csb.front() << " " << csb.back() << endl;
sb.push_back("asd");
cout << sb.front() << " " << sb.back() << endl;
sb.pop_back();
cout << sb.front() << " " << sb.back() << endl;
cout << sb.empty() << " " << sb.size() << endl;
system("pause");
return 0;
}
12.6:
#include<iostream>
using namespace std;
#include<vector>
vector<int>* func(vector<int>&v)
{
return new vector<int>(v);
}
vector<int>* func2()
{
int i = 0;
vector<int>vec;
while (cin >> i)
{
vec.push_back(i);
}
vector<int>* p = func(vec);
return p;
}
void print()
{
vector<int>* q = func2();
for (auto it = (*q).begin(); it != q->end(); ++it)
{
cout << *it << " ";
}cout << endl;
delete q;
q = nullptr;
}
int main()
{
print();
system("pause");
return 0;
}
12.7:
#include<iostream>
using namespace std;
#include<vector>
shared_ptr<vector<int>> func()
{
return make_shared<vector<int>>();
}
shared_ptr<vector<int>> func2(shared_ptr<vector<int>> v)
{
int i = 0;
while (cin >> i)
{
v->push_back(i);
}
return v;
}
void print(shared_ptr<vector<int>> vec)
{
for (auto it = (*vec).begin(); it != vec->end(); ++it)
{
cout << *it << " ";
}cout << endl;
}
int main()
{
auto vec = func2(func());
print(vec);
system("pause");
return 0;
}
12.14:
#include <iostream>
#include <string>
#include <memory>
struct connection {
std::string ip;
int port;
connection(std::string ip_, int port_) :ip(ip_), port(port_) { }
};
struct destination {
std::string ip;
int port;
destination(std::string ip_, int port_) :ip(ip_), port(port_) { }
};
connection connect(destination* pDest)
{
std::shared_ptr<connection> pConn(new connection(pDest->ip, pDest->port));
std::cout << "creating connection(" << pConn.use_count() << ")" << std::endl;
return *pConn;
}
void disconnect(connection pConn)
{
std::cout << "connection close(" << pConn.ip << ":" << pConn.port << ")" << std::endl;
}
void end_connection(connection* pConn)
{
disconnect(*pConn);
}
void f(destination& d)
{
connection conn = connect(&d);
std::shared_ptr<connection> p(&conn, end_connection);
std::cout << "connecting now(" << p.use_count() << ")" << std::endl;
}
int main()
{
destination dest("202.118.176.67", 3316);
f(dest);
}
12.15:
#include <iostream>
#include <string>
#include <memory>
struct connection {
std::string ip;
int port;
connection(std::string ip_, int port_) :ip(ip_), port(port_) { }
};
struct destination {
std::string ip;
int port;
destination(std::string ip_, int port_) :ip(ip_), port(port_) { }
};
connection connect(destination* pDest)
{
std::shared_ptr<connection> pConn(new connection(pDest->ip, pDest->port));
std::cout << "creating connection(" << pConn.use_count() << ")" << std::endl;
return *pConn;
}
void disconnect(connection pConn)
{
std::cout << "connection close(" << pConn.ip << ":" << pConn.port << ")" << std::endl;
}
//void end_connection(connection* pConn)
//{
// disconnect(*pConn);
//}
void f(destination& d)
{
connection conn = connect(&d);
std::shared_ptr<connection> p(&conn, [](connection* pConn) {disconnect(*pConn); });
std::cout << "connecting now(" << p.use_count() << ")" << std::endl;
}
int main()
{
destination dest("202.118.176.67", 3316);
f(dest);
}
12.19:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
class StrBlobPtr;
class StrBlob
{
public:friend class StrBlobPtr;
using size_type = vector<string>::size_type;
StrBlob() :data(make_shared<vector<string>>()) {};
StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il)) {};
size_type size() { return data->size(); }
bool empty()const { return data->empty(); }
void push_back(const string& s) { data->push_back(s); }
void pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
string& front()
{
check(0, "front on empty StrBlob");
return data->front();
}
string& back()
{
check(0, "front on empty StrBlob");
return data->back();
}
const string& front()const
{
check(0, "front on empty StrBlob");
return data->front();
}
const string& back()const
{
check(0, "front on empty StrBlob");
return data->back();
}
StrBlobPtr begin();
StrBlobPtr end();
private:
shared_ptr<vector<string>>data;
void check(size_type i, const string& msg)const
{
if (i >= data->size())
{
throw out_of_range(msg);
}
}
};
class StrBlobPtr
{
public:
StrBlobPtr() :curr(0) {}
StrBlobPtr(StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz) {}
string& deref()const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
StrBlobPtr& incr()
{
check(curr, "increment past end of StrBlobptr");
++curr;
return *this;
}
bool operator==(const StrBlobPtr& a) { return this->curr == a.curr; }
bool operator!=(const StrBlobPtr& a) { return !this->operator==(a); }
private:
weak_ptr<vector<string>>wptr;
size_t curr;
shared_ptr<vector<string>> 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;
}
};
StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this); }
StrBlobPtr StrBlob::end()
{
auto ret = StrBlobPtr(*this, data->size());
return ret;
}
12.20:
#include<iostream>
using namespace std;
#include<vector>
#include"StrBlob.h"
#include<string>
#include<fstream>
int main()
{
ifstream ifs("1.txt");
string s;
StrBlob blob;
while (getline(ifs, s))
{
blob.push_back(s);
}
for (StrBlobPtr pbeg(blob.begin()), pend(blob.end()); pbeg != pend; pbeg.incr())
{
cout << pbeg.deref() << endl;
}
return 0;
}
12.22:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
class constStrBlobPtr;
class StrBlob
{
public:friend class constStrBlobPtr;
using size_type = vector<string>::size_type;
StrBlob() :data(make_shared<vector<string>>()) {};
StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il)) {};
size_type size() { return data->size(); }
bool empty()const { return data->empty(); }
void push_back(const string& s) { data->push_back(s); }
void pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
string& front()
{
check(0, "front on empty StrBlob");
return data->front();
}
string& back()
{
check(0, "front on empty StrBlob");
return data->back();
}
const string& front()const
{
check(0, "front on empty StrBlob");
return data->front();
}
const string& back()const
{
check(0, "front on empty StrBlob");
return data->back();
}
constStrBlobPtr begin()const;
constStrBlobPtr end()const;
private:
shared_ptr<vector<string>>data;
void check(size_type i, const string& msg)const
{
if (i >= data->size())
{
throw out_of_range(msg);
}
}
};
class constStrBlobPtr
{
public:
constStrBlobPtr() :curr(0) {}
constStrBlobPtr(const StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz) {}
const string& deref()const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
constStrBlobPtr& incr()
{
check(curr, "increment past end of StrBlobptr");
++curr;
return *this;
}
bool operator==(const constStrBlobPtr& a) { return this->curr == a.curr; }
bool operator!=(const constStrBlobPtr& a) { return !this->operator==(a); }
private:
weak_ptr<vector<string>>wptr;
size_t curr;
shared_ptr<vector<string>> 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;
}
};
constStrBlobPtr StrBlob::begin()const { return constStrBlobPtr(*this); }
constStrBlobPtr StrBlob::end()const
{
auto ret = constStrBlobPtr(*this, data->size());
return ret;
}
12.23:
#include<iostream>
using namespace std;
#include<cstring>
int main()
{
char* p = new char[strlen("hello" "world") + 1]();
strcpy_s(p,strlen("hello")+1, "hello");
strcat_s(p, strlen("hello" "world") + 1,"world");
cout << p << endl;
delete[] p;
p = nullptr;
string str3("hello");
string str4("world");
p = new char[str3.size() + str4.size() + 1]();
strcpy_s(p, str3.size() + str4.size() + 1, (str3 + str4).c_str());
cout << p << endl;
return 0;
}
12.24:
#include<iostream>
using namespace std;
#include<cstring>
int main()
{
string a;
cin >> a;
char* p = new char[a.size()+1];
strcpy_s(p, a.size() + 1, a.c_str());
cout << p << endl;
delete[] p;
return 0;
}
12.26:
#include<iostream>
using namespace std;
#include<memory>
int main()
{
allocator<string>alloc;
auto p = alloc.allocate(10);
string s;
string* q = p;
while (cin >> s && q != p + 10)
{
alloc.construct(q++, s);
}
const size_t size = q - p;
cout << size << endl;
while (q != p)
{
cout << *--q << endl;
alloc.destroy(q);
}
alloc.deallocate(p, 10);
return 0;
}
12.27:
.h文件:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<map>
#include<set>
#include<fstream>
#include<sstream>
#include<string>
using line_no = size_t;
class QueryResult;
class TextQuery
{
public:
TextQuery(ifstream&is):file(new vector<string>)
{
string line;
string word;
while (getline(is, line))
{
file->push_back(line);//存入一行
int n = file->size() - 1;
istringstream in_is(line);
{
while (in_is >> word)//存入单词
{
shared_ptr<set<line_no>>& p = word_line[word];
if (!p)
{
p.reset(new set<line_no>());
}
p->insert(n);
}
}
}
}
QueryResult query(const string&)const;
private:
shared_ptr <vector<string>>file;
map<string, shared_ptr<set<line_no>>> word_line;
};
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& qr);
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;
};
QueryResult TextQuery::query(const string&sought)const
{
static shared_ptr<set<line_no>>nodata(new set<line_no>);
auto loc = word_line.find(sought);
if (loc == word_line.end())
{
return QueryResult(sought, nodata, file);
}
else
{
return QueryResult(sought, loc->second, file);
}
}
ostream& print(ostream& os, const QueryResult& qr)
{
os << qr.sought << " occurs " << qr.lines->size() << " "
<< (qr.lines->size() > 1 ? "times" : "time") << endl;
for (auto num : *qr.lines)
{
os << "\t(line " << num + 1 << ") "
<< *(qr.file->begin() + num) << endl;
}
return os;
}
.cpp文件:
#include<iostream>
using namespace std;
#include<memory>
#include"query.h"
void runQueries(ifstream& infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to llok for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q")
{
break;
}
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream ifs("1.txt");
runQueries(ifs);
return 0;
}
12.28:
#include<iostream>
using namespace std;
#include<vector>
#include<map>
#include<set>
#include<fstream>
#include<sstream>
#include<string>
using line_no = size_t;
int main()
{
ifstream ifs("1.txt");
string line;
string word;
vector<string>file;
map<string, set<line_no>> word_line;
while (getline(ifs, line))
{
file.push_back(line);//存入一行
int n = file.size() - 1;
istringstream in_is(line);
while (in_is >> word)//存入单词
{
word_line[word].insert(n);
}
}
while (true)
{
cout << "enter word to llok for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q")
{
break;
}
auto loc = word_line.find(s);
if (loc == word_line.end())
{
cout << s << " occurs 0 time" << endl;
}
else
{
cout << s << " occurs " << loc->second.size() << (loc->second.size() > 1 ? " times " : " time ")
<< endl;
for (auto i : loc->second)
{
cout << "\t(line " << i + 1 << " ) " << file[i] << endl;
}
}
}
}
12.29:
do {
std::cout << "enter word to look for, or q to quit: ";
string s;
if (!(std::cin >> s) || s == "q") break;
print(std::cout, tq.query(s)) << std::endl;
} while ( true );
12.32:
strblob.h:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
class constStrBlobPtr;
class StrBlob
{
public:friend class constStrBlobPtr;
using size_type = vector<string>::size_type;
StrBlob() :data(make_shared<vector<string>>()) {};
StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il)) {};
size_type size() { return data->size(); }
bool empty()const { return data->empty(); }
void push_back(const string& s) { data->push_back(s); }
void pop_back()
{
check(0, "pop_back on empty StrBlob");
data->pop_back();
}
string& front()
{
check(0, "front on empty StrBlob");
return data->front();
}
string& back()
{
check(0, "front on empty StrBlob");
return data->back();
}
const string& front()const
{
check(0, "front on empty StrBlob");
return data->front();
}
const string& back()const
{
check(0, "front on empty StrBlob");
return data->back();
}
constStrBlobPtr begin()const;
constStrBlobPtr end()const;
private:
shared_ptr<vector<string>>data;
void check(size_type i, const string& msg)const
{
if (i >= data->size())
{
throw out_of_range(msg);
}
}
};
class constStrBlobPtr
{
public:
constStrBlobPtr() :curr(0) {}
constStrBlobPtr(const StrBlob& a, size_t sz = 0) :wptr(a.data), curr(sz) {}
const string& deref()const
{
auto p = check(curr, "dereference past end");
return (*p)[curr];
}
constStrBlobPtr& incr()
{
check(curr, "increment past end of StrBlobptr");
++curr;
return *this;
}
bool operator==(const constStrBlobPtr& a) { return this->curr == a.curr; }
bool operator!=(const constStrBlobPtr& a) { return !this->operator==(a); }
private:
weak_ptr<vector<string>>wptr;
size_t curr;
shared_ptr<vector<string>> 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;
}
};
constStrBlobPtr StrBlob::begin()const { return constStrBlobPtr(*this); }
constStrBlobPtr StrBlob::end()const
{
auto ret = constStrBlobPtr(*this, data->size());
return ret;
}
query.h:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<map>
#include<set>
#include<fstream>
#include<sstream>
#include<string>
#include"StrBlob.h"
using line_no = size_t;
class QueryResult;
class TextQuery
{
public:
TextQuery(ifstream&is):file(new StrBlob)
{
string line;
string word;
while (getline(is, line))
{
file->push_back(line);//存入一行
int n = file->size() - 1;
istringstream in_is(line);
{
while (in_is >> word)//存入单词
{
shared_ptr<set<line_no>>& p = word_line[word];
if (!p)
{
p.reset(new set<line_no>());
}
p->insert(n);
}
}
}
}
QueryResult query(const string&)const;
private:
shared_ptr<StrBlob> file;
map<string, shared_ptr<set<line_no>>> word_line;
};
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& qr);
public:
QueryResult(string s,shared_ptr<set<line_no>>p,shared_ptr<StrBlob>f):
sought(s),lines(p),file(f){}
private:
string sought;
shared_ptr<set<line_no>>lines;
shared_ptr<StrBlob>file;
};
QueryResult TextQuery::query(const string&sought)const
{
static shared_ptr<set<line_no>>nodata(new set<line_no>);
auto loc = word_line.find(sought);
if (loc == word_line.end())
{
return QueryResult(sought, nodata, file);
}
else
{
return QueryResult(sought, loc->second, file);
}
}
ostream& print(ostream& os, const QueryResult& qr)
{
os << qr.sought << " occurs " << qr.lines->size() << " "
<< (qr.lines->size() > 1 ? "times" : "time") << endl;
for (auto num : *qr.lines)
{
constStrBlobPtr p(*qr.file, num);
os << "\t(line " << num + 1 << ") "
<< p.deref() << endl;
}
return os;
}
.cpp
#include<iostream>
using namespace std;
#include<memory>
#include"query.h"
void runQueries(ifstream& infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to llok for, or q to quit: ";
string s;
if (!(cin >> s) || s == "q")
{
break;
}
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream ifs("1.txt");
runQueries(ifs);
return 0;
}
12.33:
#pragma once
#include<iostream>
using namespace std;
#include<vector>
#include<map>
#include<set>
#include<fstream>
#include<sstream>
#include<string>
#include"StrBlob.h"
using line_no = size_t;
class QueryResult;
class TextQuery
{
public:
TextQuery(ifstream&is):file(new StrBlob)
{
string line;
string word;
while (getline(is, line))
{
file->push_back(line);//存入一行
int n = file->size() - 1;
istringstream in_is(line);
{
while (in_is >> word)//存入单词
{
shared_ptr<set<line_no>>& p = word_line[word];
if (!p)
{
p.reset(new set<line_no>());
}
p->insert(n);
}
}
}
}
QueryResult query(const string&)const;
private:
shared_ptr<StrBlob> file;
map<string, shared_ptr<set<line_no>>> word_line;
};
class QueryResult
{
friend ostream& print(ostream& os, const QueryResult& qr);
public:
QueryResult(string s,shared_ptr<set<line_no>>p,shared_ptr<StrBlob>f):
sought(s),lines(p),file(f){}
set<size_t>::const_iterator begin() const { return lines->begin(); }
set<size_t>::const_iterator end() const { return lines->end(); }
shared_ptr<StrBlob> get_file() { return file; }
private:
string sought;
shared_ptr<set<line_no>>lines;
shared_ptr<StrBlob>file;
};
QueryResult TextQuery::query(const string&sought)const
{
static shared_ptr<set<line_no>>nodata(new set<line_no>);
auto loc = word_line.find(sought);
if (loc == word_line.end())
{
return QueryResult(sought, nodata, file);
}
else
{
return QueryResult(sought, loc->second, file);
}
}
ostream& print(ostream& os, const QueryResult& qr)
{
os << qr.sought << " occurs " << qr.lines->size() << " "
<< (qr.lines->size() > 1 ? "times" : "time") << endl;
for (auto num : *qr.lines)
{
constStrBlobPtr p(*qr.file, num);
os << "\t(line " << num + 1 << ") "
<< p.deref() << endl;
}
return os;
}