8.1
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
istream &f(istream &i)
{
string s;
while(i>>s){
cout<<s<<" ";
}
i.clear();
return i;
}
int main(int argc, char *argv[])
{
f(cin);
system("PAUSE");
return 0;
}
8.4
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<string> ss;
string temp;
ifstream in("a.txt", ifstream::in);
if(in){
while(getline(in,temp)){
ss.push_back(temp);
}
}
in.close();
for(auto s:ss){
cout<<s<<endl;
}
system("PAUSE");
return 0;
}
8.5
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<string> ss;
string temp;
ifstream in("a.txt", ifstream::in);
if(in){
while(in>>temp){
ss.push_back(temp);
}
}
in.close();
for(auto s:ss){
cout<<s<<endl;
}
system("PAUSE");
return 0;
}
8.9
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<string> ss;
string temp;
ifstream in("a.txt", ifstream::in);
if(in){
while(getline(in,temp)){
istringstream record(temp);
cout<<record.str()<<endl;
ss.push_back(temp);
}
}
in.close();
/*for(auto s:ss){
cout<<s<<endl;
}*/
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<string> ss;
string temp;
ifstream in("a.txt", ifstream::in);
if(in){
while(getline(in,temp)){
ss.push_back(temp);
}
}
in.close();
for(auto s:ss){
istringstream record(s);
while(record>>temp){
cout<<temp<<endl;
}
}
system("PAUSE");
return 0;
}
8.13
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
struct PersonInfo
{
string name;
vector<string> phones;
};
bool valid(const string &s, string::size_type num = 10)
{
return (s.size() == num);
};
string format(string s)
{
return "["+s+"]";
};
int main(int argc, char *argv[])
{
string line, word;
vector<PersonInfo> people;
ifstream in("phone.txt");
if (in)
{
while (getline(in,line))
{
PersonInfo info;
istringstream record(line);
record>>word;
info.name = word;
while(record>>word)
{
info.phones.push_back(word);
}
people.push_back(info);
}
}
//check person info
for (const auto &entry:people)
{
ostringstream formatted, badNums;
for(const auto &num:entry.phones){
if(!valid(num)){
badNums<<" "<<num;
}else{
formatted<<" "<<format(num);
}
}
if(badNums.str().empty())
{
cout<< entry.name << " " << formatted.str() << endl;
}else{
cerr<< "input error: " << entry.name << " " <<" invalid number(s) " << badNums.str() << endl;
}
}
system("PAUSE");
return 0;
}
9.2
#include <cstdlib>
#include <iostream>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char *argv[])
{
list<deque<int>> ls;
system("PAUSE");
return 0;
}
9.4
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
bool findByIt(vector<int>::iterator &it1,
vector<int>::iterator &it2, const int c)
{
while (it1 != it2){
if (*it1 == c){
return true;
}
it1++;
}
return false;
};
int main(int argc, char *argv[])
{
vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
cout << findByIt(vec.begin(), vec.end(), 8) << endl;//1
cout << findByIt(vec.begin(), vec.end(), 12)<<endl;//0
system("PAUSE");
return 0;
}
9.6
不支持“<”操作。
9.7
size_type
9.8
const_reference reference
9.13
#include <cstdlib>9.14
#include <iostream>
#include <list>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec = { 1, 2, 3, 4, 5 };
vector<double> vec1(vec.begin(), vec.end());
//list<int> ls = { 1, 2, 3, 4, 5 };
//vector<double> vec1(ls.begin(), ls.end());
for (auto i : vec1){
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>#include <iostream>#include <string>#include <list>#include <vector>using namespace std;int main(int argc, char *argv[]){list<char *> ls = {"what", "is", "your","name","?"};vector<string> vec1;vec1.assign(ls.begin(), ls.end());for (auto i:vec1){cout << i << " ";}cout << endl;system("PAUSE");return 0;}
9.15
#include <cstdlib>9.16
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec1 = { 1, 2, 3, 4, 5 };
//vector<int> vec2 = { 1, 2, 3, 4, 5 };
vector<int> vec2 = { 1, 2, 3, 4};
if (vec1 == vec2){
cout << "vec1 == vec2";
}
else{
cout << "vec1 != vec2";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>#include <iostream>#include <vector>#include <list>using namespace std;int main(int argc, char *argv[]){vector<int> vec1 = { 1, 2, 3, 4, 5 };list<int> ls1 = { 1, 2, 3, 4, 5 };list<int>::iterator itls = ls1.begin();vector<int>::iterator itvec = vec1.begin();//itls++;if (*itls == *itvec){cout << "元素相等";}else{cout << "元素不等";}cout << endl;system("PAUSE");return 0;}9.17
元素类型必须支持“<”操作
9.18
#include <cstdlib>9.19
#include <iostream>
#include <string>
#include <deque>
using namespace std;
int main(int argc, char *argv[])
{
deque<string> de;
string word;
while (cin >> word)
{
de.push_back(word);
}
deque<string>::iterator it1 = de.begin();
deque<string>::iterator it2 = de.end();
for (; it1 != it2; it1++){
cout << *it1 << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>9.20
#include <iostream>
#include <string>
#include <list>
using namespace std;
int main(int argc, char *argv[])
{
list<string> ls;
string word;
while (cin >> word)
{
ls.push_back(word);
}
list<string>::iterator it1 = ls.begin();
list<string>::iterator it2 = ls.end();
for (; it1 != it2; it1++){
cout << *it1 << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>9.24
#include <iostream>
#include <list>
#include <deque>
using namespace std;
int main(int argc, char *argv[])
{
deque<int> deq1, deq2;
deque<int>::iterator itd11 = deq1.begin();
deque<int>::iterator itd21 = deq2.begin();
list<int> ls;
int num;
while (cin >> num)
{
ls.push_back(num);
}
for (auto i : ls){
if (i % 2){
itd11 = deq1.insert(itd11, i);
}
else{
itd21 = deq2.insert(itd21, i);
}
}
for (auto j : deq1){
cout << "deq1:" << j << " ";
}
for (auto k : deq2){
cout << "deq2:" << k << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
//vector<int> vec;
vector<int> vec{1,2,3,4,5};
cout<<vec.at(0)<<" "<<vec[0]<<" " << vec.front()<<" "<<(*vec.begin());
cout << endl;
system("PAUSE");
return 0;
}
9.25
#include <cstdlib>
#include <iostream>
#include <list>
using namespace std;
int main(int argc, char *argv[])
{
list<int> ls{1,2,3,4,5};
//ls.erase(ls.begin(), ls.begin());//如果相等则不删除任何值
//ls.erase(ls.end(), ls.end());////如果相等则不删除任何值
ls.erase(++(ls.begin()), ls.end());//删除与范围相等个数的值
for (auto i : ls){
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
9.26
#include <cstdlib>
#include <iostream>
#include <list>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
vector<int> vec(begin(ia), end(ia));
list<int> ls(begin(ia), end(ia));
vector<int>::iterator itvec = vec.begin();
list<int>::iterator itls = ls.begin();
while (itvec != vec.end()){
if (!(*itvec % 2)){
itvec = vec.erase(itvec);
}
else{
itvec++;
}
}
while (itls != ls.end())
{
if (*itls % 2){
itls = ls.erase(itls);
}
else{
itls++;
}
}
for (auto i : vec){
cout << i << " ";
}
cout << endl;
for (auto i : ls){
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
9.27
#include <cstdlib>9.28
#include <iostream>
#include <forward_list>
using namespace std;
int main(int argc, char *argv[])
{
forward_list<int> flst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto prev = flst.before_begin();
auto curr = flst.begin();
while (curr != flst.end())
{
if (*curr % 2)
{
curr = flst.erase_after(prev);
}
else{
prev = curr;
++curr;
}
}
for (auto i : flst)
{
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <forward_list>
#include <string>
using namespace std;
void f(forward_list<string> &flst, const string str1, const string str2)
{
auto prev = flst.before_begin();
auto curr = flst.begin();
bool isInList = false;
while (curr != flst.end())
{
if (*curr == str1)
{
curr = flst.insert_after(curr,str2);
++curr;
isInList = true;
}
else
{
prev = curr;
if (++curr == flst.end())
{
if (!isInList)
{
flst.insert_after(prev, str2);
}
}
}
}
};
int main(int argc, char *argv[])
{
forward_list<string> flst = {"what", "your", "name","this","name"};
//f(flst, "name", "is");//what your name is this name is
f(flst, "book", "is");//what your name this name is
for (auto i : flst)
{
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
9.31
list 迭代器只实现了,++和--,操作符运算,因为是链表结构,所以insert之后它的迭代器仍然指向有效位置。所以没必为迭代器再次赋值。
而forward_list不能获得当前元素的前驱,所以不能用--运算符。
#include <cstdlib>
#include <iostream>
#include <list>
#include <forward_list>
using namespace std;
int main(int argc, char *argv[])
{
list<int> lst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//forward_list<int> flst = { 0, 1, 2, 2, 4, 5, 6, 7, 8, 9 };
forward_list<int> flst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto itlst = lst.begin();
auto itflst = flst.begin();
auto prev = flst.before_begin();
while (itlst != lst.end())
{
if (*itlst % 2)
{
lst.insert(itlst, *itlst);
itlst++;
}
else
{
itlst = lst.erase(itlst);
}
}
while (itflst != flst.end())
{
if (*itflst % 2)
{
itflst = flst.insert_after(itflst, *itflst);
prev = itflst;
itflst++;
}
else
{
itflst = flst.erase_after(prev);
}
}
cout << "list:" << endl;
for (auto i:lst)
{
cout << i << " ";
}
cout<<endl <<"forward_list:" <<endl;
for (auto i : flst)
{
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
9.34
不正确,如果是奇数,则迭代器应该再加一次,才能指向被插入元素的下一个元素的位置。
9.41
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<char> v = { 'a', 'b', 'c', 'd', 'e' };
string str(v.begin(), v.end());
cout << endl;
system("PAUSE");
return 0;
}
9.42
先预留100个字符空间。避免重新分配空间。
9.43 9.44
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
void f(string &str, const string oldVal, const string newVale)
{
cout << str << endl;
//find oldVal
string::size_type len = oldVal.size();
string::size_type pos = 0;
string temp;
while (pos != str.size())
{
temp = str.substr(pos, len);
if (temp == oldVal){
/*str.erase(pos, len);
str.insert(pos,newVale);*/
str.replace(pos, len, newVale);
}
pos++;
}
cout << str << endl;
};
int main(int argc, char *argv[])
{
string s("now that is it has no is");
f(s, "is","was");
cout << endl;
system("PAUSE");
return 0;
}
9,45
注意,迭代器版本的insert只能接受,字符的插入
#include <cstdlib>9.46
#include <iostream>
#include <string>
using namespace std;
string f(string name,const string &pre,const string &aft)
{
auto it = name.begin();
name.insert(it, { pre[0],pre[1],pre[2] });
name.append(aft);
return name;
};
int main(int argc, char *argv[])
{
cout << f("marthin", "Mr.", "Jr.");
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
string f(string name,const string &pre,const string &aft)
{
name.insert(0, pre);
name.insert(name.size(), aft);
return name;
};
int main(int argc, char *argv[])
{
cout << f("marthin", "Mr.", "Jr.");
cout << endl;
system("PAUSE");
return 0;
}
9.47
#include <cstdlib>9.49
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
string str = "ab2c3d7R4E6";
string numbers = "23467";
string chars = "abcdRE";
string::size_type pos = 0;
while ((pos = str.find_first_of(numbers, pos)) != string::npos)
{
cout << str.at(pos) << " ";
++pos;
}
cout << endl;
pos = 0;
while ((pos = str.find_first_of(chars, pos)) != string::npos)
{
cout << str.at(pos) << " ";
++pos;
}
cout << endl;
pos = 0;
while ((pos = str.find_first_not_of(chars, pos)) != string::npos)
{
cout << str.at(pos) << " ";
++pos;
}
cout << endl;
pos = 0;
while ((pos = str.find_first_not_of(numbers, pos)) != string::npos)
{
cout << str.at(pos) << " ";
++pos;
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>9.50
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
ifstream in;
string temp, maxStr, ascender("bdfhiklt"), descender("gjpqy"), normal("acemnorsuvwxz");
vector<string> vec;
in.open("words.txt");
if (in)
{
while (in >> temp)
{
vec.push_back(temp);
}
}
for (auto str : vec)
{
if (str.find_first_of(ascender) == string::npos && str.find_first_of(descender) == string::npos)
{
cout << str << endl;
if (str.size() > maxStr.size())
{
maxStr = str;
}
}
}
cout << maxStr << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>10.1 10.2
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<string> vec = {"1","2","3","4","5","-6"};
int sum = 0;
for (string i:vec)
{
sum += stoi(i);
}
cout << sum << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
//vector<int> vec;
//int temp;
vector<string> vec;
string temp;
while (cin >> temp)
{
vec.push_back(temp);
}
//auto i = count(vec.begin(), vec.end(), 5);
auto i = count(vec.begin(), vec.end(), "is");
cout << i << endl;
system("PAUSE");
return 0;
}
10.5
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
char * roster1[] = { "hello" };
char * roster2[] = { "hello" };
cout << equal(begin(roster1),end(roster1),begin(roster2))<<endl;
system("PAUSE");
return 0;
}
10.6
#include <cstdlib>10.7
#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec;
fill_n(back_inserter(vec), 10, 0);
for (int i:vec)
{
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
(1) 不正确,目的序列没有足够的元素个数。
(2)不正确,reserve只是分配了所需空间,但是并不改变元素个数,如果用resize就正确了。
10.9
#include <cstdlib>10.10
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;
void show(const vector<string> &vec)
{
for (string i : vec)
{
cout << i << " ";
}
cout << endl;
}
void elimDups(vector<string> &words)
{
show(words);
sort(words.begin(), words.end());
show(words);
auto end_unique = unique(words.begin(), words.end());
show(words);
words.erase(end_unique, words.end());
show(words);
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
while (cin>>temp)
{
vec.push_back(temp);
}
elimDups(vec);
system("PAUSE");
return 0;
}
我认为不改变容器大小的原因是,某些改变容器大小的操作会使迭代器失效。
10.11
#include <cstdlib>10.12
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;
void show(const vector<string> &vec)
{
for (string i : vec)
{
cout << i << " ";
}
cout << endl;
}
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
void elimDups(vector<string> &words)
{
show(words);
sort(words.begin(), words.end());
show(words);
auto end_unique = unique(words.begin(), words.end());
show(words);
words.erase(end_unique, words.end());
show(words);
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in;
in.open("10.txt");
while (in>>temp)
{
vec.push_back(temp);
}
elimDups(vec);
stable_sort(vec.begin(), vec.end(),isShorter);
show(vec);
system("PAUSE");
return 0;
}
#include <cstdlib>10.13
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;
class Sales_data
{
public:
Sales_data(const string s) :bookNo(s){}
string isbn() const { return bookNo; }
private:
string bookNo;
};
void show(const vector<Sales_data> &vec)
{
for (auto i : vec)
{
cout << i.isbn() << " ";
}
cout << endl;
}
bool compareIsbn(const Sales_data &s1, const Sales_data &s2)
{
bool b = s1.isbn() > s2.isbn();
return b;
}
int main(int argc, char *argv[])
{
vector<Sales_data> vec = { Sales_data("123-445-667"),
Sales_data("826-699-542"), Sales_data("454-336-728"),
Sales_data("365-425-424") };
show(vec);
sort(vec.begin(), vec.end(), compareIsbn);
show(vec);
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void show(const vector<string> &vec)
{
for (auto i : vec)
{
cout << i << " ";
}
cout << endl;
}
bool compare(const string &s)
{
return s.size() >= 5;
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in("10.txt");
while (in>>temp)
{
vec.push_back(temp);
}
show(vec);
auto end_part = partition(vec.begin(),vec.end(), compare);
show(vec);
vec.erase(end_part, vec.end());
show(vec);
system("PAUSE");
return 0;
}
10.14
#include <cstdlib>10.15
#include <iostream>
#include <vector>
using namespace std;
auto f = [](int a, int b)->int{return a + b; };
int main(int argc, char *argv[])
{
cout << f(3, 4) << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
using namespace std;
int f()
{
int a = 0;
auto f = [a](int b)->int{return a + b; };
return f(3);
}
int f(int a)
{
auto f = [a](int b)->int{return a + b; };
return f(3);
}
int main(int argc, char *argv[])
{
cout << f() << endl;
cout << f(3) << endl;
system("PAUSE");
return 0;
}
10.16
#include <cstdlib>10.17
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void show(const vector<string> &v, string prefix = "", string suffix = "",
string perPre = "", string perSuf = " ")
{
cout << prefix;
for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre+s+perSuf ; });
cout << suffix << endl;
}
void elimDups(vector<string> &v)
{
show(v,"original: ");
sort(v.begin(), v.end());
show(v,"sort: ");
auto end_uniq = unique(v.begin(), v.end());
show(v, "unique: ");
v.erase(end_uniq, v.end());
show(v,"erase: ");
}
void biggies(vector<string> &v, const vector<string>::size_type sz)
{
elimDups(v);
stable_sort(v.begin(), v.end(), [](const string &a, const string &b){return a.size() < b.size(); });
show(v, "stable_sort: ");
auto fir_find = find_if(v.begin(), v.end(), [sz](const string &a){return a.size() >= sz; });
for_each(fir_find, v.end(), [](const string &a){cout << a << " "; });
cout << endl;
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in("10.txt");
while (in>>temp)
{
vec.push_back(temp);
}
biggies(vec, 4);
system("PAUSE");
return 0;
}
#include <cstdlib>10.18
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Sales_data
{
public:
Sales_data(const string s) :bookNo(s){}
string isbn() const { return bookNo; }
private:
string bookNo;
};
void show(const vector<Sales_data> &vec)
{
for (auto i : vec)
{
cout << i.isbn() << " ";
}
cout << endl;
}
int main(int argc, char *argv[])
{
vector<Sales_data> vec = { Sales_data("123-445-667"),
Sales_data("826-699-542"), Sales_data("454-336-728"),
Sales_data("365-425-424") };
show(vec);
sort(vec.begin(), vec.end(), [](const Sales_data &a, const Sales_data &b){return a.isbn() > b.isbn(); });
show(vec);
system("PAUSE");
return 0;
}
#include <cstdlib>10.19
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void show(const vector<string> &v, string prefix = "", string suffix = "",
string perPre = "", string perSuf = " ")
{
cout << prefix;
for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre + s + perSuf; });
cout << suffix << endl;
}
void elimDups(vector<string> &v)
{
show(v, "original: ");
sort(v.begin(), v.end());
show(v, "sort: ");
auto end_uniq = unique(v.begin(), v.end());
show(v, "unique: ");
v.erase(end_uniq, v.end());
show(v, "erase: ");
}
void biggies(vector<string> &v, const vector<string>::size_type sz)
{
elimDups(v);
auto end_part = partition(v.begin(), v.end(), [sz](const string &a){return a.size() >= sz; });
for_each(v.begin(), end_part, [](const string &a){cout << a << " "; });
cout << endl;
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in("10.txt");
while (in >> temp)
{
vec.push_back(temp);
}
biggies(vec, 5);
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void show(const vector<string> &v, string prefix = "", string suffix = "",
string perPre = "", string perSuf = " ")
{
cout << prefix;
for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre + s + perSuf; });
cout << suffix << endl;
}
void elimDups(vector<string> &v)
{
show(v, "original: ");
sort(v.begin(), v.end());
show(v, "sort: ");
auto end_uniq = unique(v.begin(), v.end());
show(v, "unique: ");
v.erase(end_uniq, v.end());
show(v, "erase: ");
}
void biggies(vector<string> &v, const vector<string>::size_type sz)
{
elimDups(v);
auto end_part = stable_partition(v.begin(), v.end(), [sz](const string &a){return a.size() >= sz; });
for_each(v.begin(), end_part, [](const string &a){cout << a << " "; });
cout << endl;
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in("10.txt");
while (in >> temp)
{
vec.push_back(temp);
}
biggies(vec, 5);
system("PAUSE");
return 0;
}
10.20
#include <cstdlib>10.21
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in("10.txt");
while (in>>temp)
{
vec.push_back(temp);
}
cout << count_if(vec.begin(), vec.end(), [](const string &s){return s.size() >= 5; });
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void fun()
{
int i = 1;
auto fc = [&i]()->bool
{
if(i > 0)
{
--i;
return true;
}
return false;
};
cout << fc() << endl;
cout << fc() << endl;
}
int main(int argc, char *argv[])
{
fun();
system("PAUSE");
return 0;
}
10.22
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
bool lengthUp(const string &s)
{
return s.size() >= 5;
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in("words.txt");
while (in >> temp)
{
vec.push_back(temp);
}
cout << count_if(vec.begin(), vec.end(), lengthUp);
cout << endl;
system("PAUSE");
return 0;
}
bind 的参数不限制
10.24
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
bool check_size(const int &i, string::size_type sz)
{
return i > sz;
}
int main(int argc, char *argv[])
{
string s = "world";
vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto find_first = find_if(vec.begin(), vec.end(), bind(check_size, placeholders::_1, s.size()));
if (find_first != vec.end())
{
cout << *find_first << endl;
}
system("PAUSE");
return 0;
}
10.25
#include <cstdlib>10.27
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
void show(const vector<string> &v, string prefix = "", string suffix = "",
string perPre = "", string perSuf = " ")
{
cout << prefix;
for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre + s + perSuf; });
cout << suffix << endl;
}
bool check_size(const string &s, string::size_type sz)
{
return s.size() >= sz;
}
void elimDups(vector<string> &v)
{
show(v, "original: ");
sort(v.begin(), v.end());
show(v, "sort: ");
auto end_uniq = unique(v.begin(), v.end());
show(v, "unique: ");
v.erase(end_uniq, v.end());
show(v, "erase: ");
}
void biggies(vector<string> &v, const vector<string>::size_type sz)
{
elimDups(v);
auto end_part = partition(v.begin(), v.end(), bind(check_size,placeholders::_1,sz));
for_each(v.begin(), end_part, [](const string &a){cout << a << " "; });
cout << endl;
}
int main(int argc, char *argv[])
{
vector<string> vec;
string temp;
ifstream in("words.txt");
while (in >> temp)
{
vec.push_back(temp);
}
biggies(vec, 5);
system("PAUSE");
return 0;
}
<pre name="code" class="cpp">#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
void show(vector<string> &v)
{
for (auto s : v)
{
cout << s << " ";
}
cout << endl;
}
void show(list<string> &l)
{
for (auto s : l)
{
cout << s << " ";
}
cout << endl;
}
int main(int argc, char *argv[])
{
vector<string> vec;
list<string> ls;
string temp;
ifstream in("double.txt");
while (in >> temp)
{
vec.push_back(temp);
}
show(vec);
sort(vec.begin(), vec.end());
show(vec);
unique_copy(vec.begin(), vec.end(), back_inserter(ls));
show(ls);
system("PAUSE");
return 0;
}
10.28
#include <cstdlib>
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>
#include <iterator>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
list<int> ls;
vector<int> vec1;
deque<int> dq;
copy(vec.begin(), vec.end(), back_inserter(vec1));//1,2,3,4,5,6,7,8,9
copy(vec.begin(), vec.end(), front_inserter(dq));//9,8,7,6,5,4,3,2,1
copy(vec.begin(), vec.end(), inserter(ls,ls.begin()));//1,2,3,4,5,6,7,8.9
cout << "vector: ";
for (auto i:vec1)
{
cout << i << " ";
}
cout << endl;
cout << "deque: ";
for (auto i : dq)
{
cout << i << " ";
}
cout << endl;
cout << "list: ";
for (auto i : ls)
{
cout << i << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
10.29
#include <cstdlib>10.30
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;
int main(int argc, char *argv[])
{
ifstream file("10.txt");
istream_iterator<string> in(file),eof;
vector<string> vec(in,eof);
for (auto s : vec)
{
cout << s << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>10.31
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
istream_iterator<int> in(cin),eof;
ostream_iterator<int> out(cout," ");
vector<int> vec(in,eof);
sort(vec.begin(), vec.end());
copy(vec.begin(), vec.end(), out);
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>10.32
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
istream_iterator<int> in(cin),eof;
ostream_iterator<int> out(cout," ");
vector<int> vec(in,eof);
sort(vec.begin(), vec.end());
unique_copy(vec.begin(),vec.end(),out);
cout << endl;
system("PAUSE");
return 0;
}
涉及到运算符重载,以后补更。
10.33
#include <cstdlib>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <string>
using namespace std;
void f(string inName, string outName1, string outName2)
{
ifstream in(inName);
ofstream out1(outName1);
ofstream out2(outName2);
if (in)
{
istream_iterator<int> itIn(in),eof;
ostream_iterator<int> itOut1(out1," ");
ostream_iterator<int> itOut2(out2," ");
while (itIn != eof)
{
if ((*itIn) % 2){
*itOut1 = *itIn;
}
else{
*itOut2 = *itIn;
}
++itIn;
}
}
in.close();
out1.close();
out2.close();
}
int main(int argc, char *argv[])
{
f("int.txt","out1.txt","out2.txt");
system("PAUSE");
return 0;
}
10.34
#include <cstdlib>10.35
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for_each(vec.crbegin(), vec.crend(), [](const int &i){cout << i << " "; });
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>10.36
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
vector<int>::iterator itb = vec.begin();
vector<int>::iterator ite = vec.end();
while (ite != itb)
{
--ite;
cout << *ite << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>10.37
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
list<int> ls = { 1, 3, 0, 7, 9, 3, 2, 0, 0, 3, 1, 0, 4, 6 };
auto zero_rit = find(ls.crbegin(), ls.crend(), 0);
cout << endl;
system("PAUSE");
return 0;
}
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
vector<int> vec{1,2,3,4,5,6,7,8,9,0};
list<int> ls;
auto l = vec.crbegin() + 3;
auto r = vec.crend() - 3;
copy(l,r,back_inserter(ls));
for_each(ls.begin(), ls.end(), [](const int &i){cout<<i<<" "; });//7 6 5 4
cout << endl;
system("PAUSE");
return 0;
}
10.42
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <fstream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
list<string> ls;
ifstream in("10.txt");
if (in)
{
istream_iterator<string> itIn(in), eof;
copy(itIn, eof, back_inserter(ls));
ls.sort();
ls.unique();
for_each(ls.begin(), ls.end(), [](const string &s){cout<<s<<" "; });//fox jumps over quick red slow the turtle
}
in.close();
cout << endl;
system("PAUSE");
return 0;
}
11.4
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <algorithm>
using namespace std;
int main(int argc, char *argv[])
{
ifstream in("words.txt");//Age has reached the end of the beginning of a word age, has! reached, the; end. of, the, beginning! of. a Word.
string temp;
string::size_type pos = 0;
map<string, size_t> word_count;
set<char> include = { '.', ',', ';', '!' };
while (in>>temp)
{
transform(temp.begin(), temp.end(),temp.begin(),tolower);
cout << temp << endl;
for (auto &c:include)
{
while ((pos = temp.find_first_of(c,pos)) != string::npos)
{
temp.erase(pos,1);
}
pos = 0;
}
++word_count[temp];
}
/*a occurs 2 times
age occurs 2 times
beginning occurs 2 times
end occurs 2 times
has occurs 2 times
of occurs 4 times
reached occurs 2 times
the occurs 4 times
word occurs 2 times
*/
for (const auto &w:word_count)
{
cout << w.first << " occurs " << w.second << ((w.second > 1) ? " times" : " time") << endl;
}
cout << endl;
system("PAUSE");
return 0;
}
11.7
#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void addAccount(map<string, vector<string>> &m, const string key, const string name = "")
{
m[key].push_back(name);
}
int main(int argc, char *argv[])
{
map<string, vector<string>> account;
addAccount(account,"A","a");
addAccount(account, "A", "b");
addAccount(account, "A", "c");
addAccount(account, "b");
for (auto &c : account)
{
cout << c.first << " : ";
for_each(c.second.begin(), c.second.end(), [](const string &s){cout << s << " "; });
cout << endl;
}
cout << endl;
system("PAUSE");
return 0;
}
11.12 11.13
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;
int main(int argc, char *argv[])
{
//pair<string, int> p;
vector<pair<string, int>> vec;
string stemp;
int itemp;
while (cin>>stemp>>itemp)
{
//p = make_pair(stemp, itemp);
//pair<string, int> p = {stemp,itemp};
pair<string, int> p(stemp,itemp);
vec.push_back(p);
}
for_each(vec.begin(), vec.end(), [](const pair<string, int> &p){cout << p.first << " " << p.second << endl; });
system("PAUSE");
return 0;
}
11.14
#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <utility>
using namespace std;
void addAccount(map<string, vector<pair<string, string>>> &m, const string key, const string name = "", const string birthday = "")
{
m[key].push_back(make_pair(name,birthday));
}
int main(int argc, char *argv[])
{
map<string, vector<pair<string, string>>> account;
addAccount(account, "A", "a","1999-9-9");
addAccount(account, "A", "b","2000-1-1");
addAccount(account, "A", "c","2014-9-9");
addAccount(account, "b");
for (auto &c : account)
{
cout << c.first << " : ";
for_each(c.second.begin(), c.second.end(), [](const pair<string, string> &s){cout << s.first << " " << s.second<<endl; });
}
cout << endl;
system("PAUSE");
return 0;
}
11.17
#include <cstdlib>
#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <iterator>
using namespace std;
int main(int argc, char *argv[])
{
vector<string> v = {"hello","wow","are","you"};
multiset<string> c;
vector<string> v1;
multiset<string> c1 = { "hello", "wow", "are", "you" };
copy(v.begin(), v.end(), inserter(c, c.end()));//支持
//copy(v.begin(), v.end(), back_inserter(c));//不支持,因为涉及到顺序问题
//copy(c1.begin(),c1.end(),inserter(v1,v1.end()));//支持
copy(c1.begin(), c1.end(), back_inserter(v1));//支持
/*auto m = c.begin();
while (m != c.end())
{
cout << *m << endl;
++m;
}*/
auto m = v1.begin();
while (m != v1.end())
{
cout << *m << endl;
++m;
}
system("PAUSE");
return 0;
}
11.18 是 map<string, size_t>::const_iterator 类型
#include <cstdlib>
#include <iostream>
#include <map>
#include <utility>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
map<string, size_t> word_count = { {"hello",1} };
map<string, size_t>::const_iterator map_it = word_count.cbegin();
cout << map_it->first << endl;
system("PAUSE");
return 0;
}
11.19
#include <cstdlib>11.20
#include <iostream>
#include <set>
#include <utility>
#include <string>
using namespace std;
class Sales_data
{
public:
Sales_data(const string s) :bookNo(s){}
string isbn() const { return bookNo; }
private:
string bookNo;
};
bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs)
{
return lhs.isbn() < rhs.isbn();
}
int main(int argc, char *argv[])
{
Sales_data b("123-456-789");
multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)> bookstore({ b });
multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)>::const_iterator book_it = bookstore.cbegin();
if (book_it != bookstore.cend())
{
Sales_data a(*book_it);
cout << a.isbn() << endl;
}
system("PAUSE");
return 0;
}
#include <cstdlib>#include <iostream>#include <map>#include <utility>#include <string>using namespace std;int main(int argc, char *argv[]){map<string, size_t> word_count;string word;while (cin>>word){auto ret = word_count.insert({word,1});if (!ret.second){++(ret.first->second);}}for (auto &p : word_count){cout << p.first << " " << p.second << endl;}system("PAUSE");return 0;}
11.21
关键字word的size_t 数量加一。
11.24
插入一个 关键字 为 0 的元素, 并将它赋值为 1
11.25
会报错,因为没有分配空间
11.26
1、key_type 2、mapped_type
#include <cstdlib>
#include <iostream>
#include <map>
using namespace std;
int main(int argc, char *argv[])
{
map<string, int> m = { { "a", 0 }, { "b", 1 }, { "c", 2 } };
map<string, int>::key_type a = "a";
cout << m[a] << endl;
cout << endl;
system("PAUSE");
return 0;
}
11.28
#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
map<string, vector<int>> m;
vector<int> a = { 1, 2, 3};
vector<int> b = { 4, 5, 6 };
vector<int> c = { 7, 8, 9 };
m["a"] = a;
m["b"] = b;
m["c"] = c;
map<string,vector<int>>::iterator it = m.find("a");
for_each(it->second.begin(), it->second.end(), [](const int &i){cout << i << " "; });
cout << endl;
system("PAUSE");
return 0;
}
11.30
pos.first 返回一个map迭代器,->second 标识查找关键字对应的内容
11.31 11.32
因为本来就是使用的有序容器,所以打印出来就是按字典排序的。
#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
multimap<string, string> m = { { "jack", "bookC" }, { "jack", "bookB" }, { "james", "bookA" }, { "james", "bookB" },
{ "zoe", "bookZ" }, { "zoe", "bookB" }, { "hair", "bookA" }, { "hair", "bookG" } };
multimap<string,string>::iterator it = m.find("hair");
if (it != m.end())
{
cout << "erase it" << endl;
m.erase(it);
}
for (auto p : m)
{
cout << p.first << " " << p.second << endl;
}
cout << endl;
system("PAUSE");
return 0;
}
11.33
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
map<string, string> buildMap(ifstream &map_file)
{
map<string, string> trans_map;
string key;
string value;
while (map_file>>key && getline(map_file, value))
{
if (value.size() > 1)
{
trans_map[key] = value.substr(1);
}
else
{
throw runtime_error("no rule for " + key);
}
}
return trans_map;
}
const string & transform(const string &s, const map<string, string> &m)
{
auto map_it = m.find(s);
if (map_it != m.cend())
{
return map_it->second;
}
else{
return s;
}
}
void word_transform(ifstream &map_file, ifstream &input)
{
auto trans_map = buildMap(map_file);
for_each(trans_map.begin(), trans_map.end(), [](const pair<string, string> p){cout<<p.first<<"=="<<p.second<<endl; });
string text;
while (getline(input,text))
{
istringstream stream(text);
string word;
bool firstword = true;
while (stream >> word)
{
if (firstword)
{
firstword = false;
}
else{
cout << " ";
}
cout << transform(word, trans_map);
}
cout << endl;
}
}
int main(int argc, char *argv[])
{
ifstream trans("trans.txt");
ifstream input("needtrans.txt");
word_transform(trans, input);
cout << endl;
system("PAUSE");
return 0;
}
11.34
会变成插入元素,这样转换的文本就没有起到作用。
11.35
程序依然正常运行。
11.36
它会抛出一个异常“no rule for”+key
11.38
改变类型即可。
12.1
它们共享数据
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;
class StrBlob
{
public:
typedef vector<string>::size_type size_type;
StrBlob();
~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();
private:
shared_ptr<vector<string>> data;
void check(size_type i, const string &msg) const;
};
StrBlob::StrBlob() :data(make_shared<vector<string>>())
{
}
StrBlob::~StrBlob()
{
}
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);
}
}
void StrBlob::pop_back()
{
check(0, "pop_back");
data->pop_back();
}
string& StrBlob::front()
{
check(0, "front");
return data->front();
}
string& StrBlob::back()
{
check(0, "back");
return data->back();
}
int main(int argc, char *argv[])
{
StrBlob b1;
{
StrBlob b2 = { "a", "an", "the" };
b1 = b2;
cout << b1.size() << endl;//3
cout << b2.size() << endl;//3
b2.push_back("about");
cout << b1.size() << endl;//4
cout << b2.size() << endl;//4
}
cout << endl;
system("PAUSE");
return 0;
}
12.2
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;
class StrBlob
{
public:
typedef vector<string>::size_type size_type;
StrBlob();
~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();
const string& front() const;
string& back();
const string& back() const;
private:
shared_ptr<vector<string>> data;
void check(size_type i, const string &msg) const;
};
StrBlob::StrBlob() :data(make_shared<vector<string>>())
{
}
StrBlob::~StrBlob()
{
}
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);
}
}
void StrBlob::pop_back()
{
check(0, "pop_back");
data->pop_back();
}
string& StrBlob::front()
{
check(0, "front");
return data->front();
}
const string& StrBlob::front() const
{
check(0, "const front");
return data->front();
}
string& StrBlob::back()
{
check(0, "back");
return data->back();
}
const string& StrBlob::back() const
{
check(0, "const back");
return data->back();
}
int main(int argc, char *argv[])
{
StrBlob b1;
{
StrBlob b2 = { "a", "an", "the" };
b1 = b2;
cout << b1.size() << endl;//3
cout << b2.size() << endl;//3
b2.push_back("about");
cout << b1.size() << endl;//4
cout << b2.size() << endl;//4
cout << b1.front() << endl;//a
cout << b2.back() << endl;//about
}
cout << endl;
system("PAUSE");
return 0;
}
12.3
不需要,因为它会改变vector。
12.4
因为size_type是一个无符号类型,赋值为-1它会越界,所产生的数值已经包含在了这个检测范围之中。
12.5
构造函数不能隐式转换,只能直接初始化或显式的使用构造函数。
12.6
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void setVec(vector<int> *p)
{
int temp = 0;
while (cin>>temp)
{
p->insert(p->begin(), temp);
}
}
void showVec(vector<int> *p)
{
for_each(p->begin(), p->end(), [](const int &i){cout<<i<<" "; });
}
int main(int argc, char *argv[])
{
vector<int> *p = new vector < int > ;
setVec(p);
showVec(p);
delete p;
p = nullptr;
cout << endl;
system("PAUSE");
return 0;
}
12.7
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
using namespace std;
void setVec(shared_ptr<vector<int>> &p)
{
cout << p.use_count() << endl;//1
int temp = 0;
/*while (cin>>temp)
{
p->insert(p->begin(), temp);
}*/
}
void showVec(shared_ptr<vector<int>> p)
{
cout << p.use_count() << endl;//2
for_each(p->begin(), p->end(), [](const int &i){cout<<i<<" "; });
}
int main(int argc, char *argv[])
{
shared_ptr<vector<int>> p = make_shared < vector<int> >(3,9);
cout << p.use_count() << endl;//1
setVec(p);
cout << p.use_count() << endl;//1
showVec(p);
cout << p.use_count() << endl;//1
cout << endl;
system("PAUSE");
return 0;
}
12.8
有错误,因为返回的是布尔值类型,只能是0,1这样指针所指向的内存永远无法释放。
12.9
1、会导致r所指向的内存无法释放。
2、用 share_ptr 则不会存在此问题。因为当赋值时,它会减1 r的引用计数,然后增加q的引用计数。
12.10
正确,在处理函数中有2个引用计数,结束时不会被释放掉。
12.11
会被释放掉p所指向的内存
12.12
a.合法,拷贝sp增加引用计数 b.不正确不能隐式转换 c.不正确,不能隐式转换 d.正确,函数结束时会释放掉p所指向内存。
12.13
p和sp所指向内存被释放掉
12.14 12.15
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
using namespace std;
struct destination
{
string name;
};
struct connection
{
connection(){};
connection(string n):name(n){};
string name;
};
void disconnect(connection c)
{
cout << "disconnect " << c.name <<endl;
}
connection connect(destination * d)
{
cout << "connect " << d->name << endl;
connection a;
return a;
}
void end_connection(connection *p)
{
cout << "call endconnect" << endl;
disconnect(*p);
}
void f(destination &d)
{
connection c = connect(&d);
//shared_ptr<connection>p(&c, end_connection);
shared_ptr<connection>p(&c, [](connection *c){disconnect(*c); });
}
int main(int argc, char *argv[])
{
connection c;
c.name = "connect a";
destination b;
b.name = "dest b";
f(b);
cout<< endl;
system("PAUSE");
return 0;
}
12.16
错误 1 error C2280: “std::unique_ptr<std::string,std::default_delete<_Ty>> &std::unique_ptr<_Ty,std::default_delete<_Ty>>::operator =(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)”: 尝试引用已删除的函数d:\project\c++project\primer\c11\c11\main.cpp
12.17
a. 类型不匹配 ; b .会导致后续程序错误,一旦p1 = nullptr,则pi和ix的内存被释放掉,无法正常调用;c.同b,delete pi2后也无法正常调用p2;d.可以这样用;e.可以这样用;f.同b.
12.18
一旦share_ptr引用为0,就自动释放了。
12.19 12.20
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
using namespace std;
class StrBlob
{
friend class StrBlobPtr;
public:
typedef vector<string>::size_type size_type;
StrBlob();
~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();
StrBlobPtr begin();
StrBlobPtr end();
private:
shared_ptr<vector<string>> data;
void check(size_type i, const string &msg) const;
};
class StrBlobPtr{
public:
StrBlobPtr() :curr(0){}
StrBlobPtr(StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz){}
string& deref() const;
StrBlobPtr& incr();
const size_t& getCurr() const;
private:
shared_ptr<vector<string>> check(size_t, const string&) const;
weak_ptr<vector<string>> wptr;
size_t curr;
};
StrBlobPtr StrBlob::begin(){
return StrBlobPtr(*this);
}
StrBlobPtr StrBlob::end(){
return StrBlobPtr(*this, data->size());
};
StrBlob::StrBlob() :data(make_shared<vector<string>>())
{
}
StrBlob::~StrBlob()
{
}
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);
}
}
void StrBlob::pop_back()
{
check(0, "pop_back");
data->pop_back();
}
string& StrBlob::front()
{
check(0, "front");
return data->front();
}
string& StrBlob::back()
{
check(0, "back");
return data->back();
}
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;
}
const size_t& StrBlobPtr::getCurr() const{
return curr;
}
int main(int argc, char *argv[])
{
string temp;
ifstream in("type.txt");
StrBlob sb;
StrBlobPtr sbptr(sb);
while (getline(in,temp))
{
sb.push_back(temp);
}
in.close();
size_t c = 0;
/*
Hi, How are you today?
I'am fine, tank you, and you?
I'am fine too.
GoodBye.
Bye-Bye.
*/
while (sbptr.getCurr() != sb.size())
{
cout << sbptr.deref() << endl;
sbptr.incr();
}
cout<< endl;
system("PAUSE");
return 0;
}
12.21
我认为12.21这个版本好。简练。
12.22
在StrBlobPtr里面添加一个const的构造函数。
StrBlobPtr(const StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz){}
12.23
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;
const char* connectChars(const char* t1, const int s1, const char* t2, const int s2){
int len = s1 + s2;
char *t = new char[len];
for (int i = 0; i != len; i++)
{
if (i < s1){
t[i] = t1[i];
}
else if (i >= s1)
{
t[i] = t2[i-s1];
}
}
for (int j = 0; j < len; j++)
{
cout << t[j];
}
return t;
}
const string* connectString(const string &s1, const string &s2)
{
string::size_type len = s1.length() + s2.length();
string* p = new string[len]{string(s1+s2)};
cout << *p;
return p;
}
int main(int argc, char *argv[])
{
connectChars("123",3, "456",3);//123456
cout << endl;
connectString("123", "456");//123456
cout << endl;
system("PAUSE");
return 0;
}
12.24
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
char* t = new char[2];
cin >> t;
for (int i = 0; i < 4; i++)
{
cout << t[i];
}
cout << endl;
system("PAUSE");
输入一个超出的没有发现有问题。
12.25
delete [] pa;
12.26
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;
int main(int argc, char *argv[])
{
size_t n = 5;
string s;
allocator<string> alloc;
auto const p = alloc.allocate(n);
auto q = p;
while (cin >> s && q != p + n)
{
alloc.construct(q, s);
cout << (*q )<< endl;
q++;
}
while (q != p)
{
alloc.destroy(--q);
}
alloc.deallocate(p, n);
cout << endl;
system("PAUSE");
return 0;
}
12.27
因为不理解本节的意思,所以这个自己的版本有错误,不要参考。
#ifndef __Text_Query_H__
#define __Text_Query_H__
#include <vector>
#include <string>
#include <set>
#include <map>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
class TextQuery
{
public:
TextQuery(ifstream&);
TextQuery();
void query(string word);
protected:
private:
vector<string> lines;//保存每行文本
set<unsigned int> lineNum;//保存查找单词对应的行号
map<string, set<unsigned int>> wordsNum;//保存查找过单词的列表
};
#endif
#ifndef __Query_Result_H__
#define __Query_Result_H__
using namespace std;
class QueryResult
{
public:
QueryResult();
~QueryResult();
protected:
private:
};
#endif
#include "TextQuery.h"
TextQuery::TextQuery(ifstream& f)
{
string line;
while (getline(f,line))
{
lines.push_back(line);
}
}
void TextQuery::query(string word)
{
auto b = lines.begin();
auto e = lines.end();
vector<string>::iterator it = b;
vector<string>::size_type len = lines.size();
for (int i = 0; i < len; ++it,++i)
{
istringstream record(*it);
string tempw;
while (record>>tempw)
{
if (tempw == word)
{
lineNum.insert(i);
cout << i << endl;
}
}
}
}
#include <cstdlib>
#include <iostream>
#include "TextQuery.h"
using namespace std;
int main(int argc, char *argv[])
{
ifstream infile("a.txt");
TextQuery tq(infile);
tq.query("name");
system("PAUSE");
return 0;
}
12.18
有个问题,同一行如果出现多次查询的单词,只记录一次。需要修改
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <memory>
using namespace std;
typedef vector<string>::size_type size_type;
int main(int argc, char *argv[])
{
vector<string> lines;
map<string, shared_ptr<set<vector<string>::size_type>>> wordsDic;
shared_ptr<set<vector<string>::size_type>> p;
string queryWord;
ifstream in("type.txt");
if (in){
string line;
while (getline(in, line))
{
cout << line << endl;
lines.push_back(line);
}
while (true)
{
if (!(cin >> queryWord) || queryWord == "q") break;
if (wordsDic[queryWord] == nullptr)
{
p = wordsDic[queryWord];
p.reset(new set<size_type>);
for (size_type i = 0; i < lines.size(); i++)
{
istringstream s(lines.at(i));
string temp;
while (s>>temp){
if (temp == queryWord){
p->insert(i+1);
}
}
}
}
cout << queryWord << " occurs " << p->size() << "times" << endl;
for (auto t : (*p))
{
cout << "( line " << t << " ) " << lines.at(t-1) << endl;
}
}
in.close();
}
cout << endl;
system("PAUSE");
return 0;
}
12.29
用do...while();好,第一、代码更清晰,第二、保证输入的是"q"也能执行一次。(参考12.30)
12.30
头文件
TextQuery.h
#ifndef __Text_Query_H__
#define __Text_Query_H__
#include <vector>
#include <string>
#include <set>
#include <map>
#include <fstream>
#include <iostream>
#include <sstream>
#include <memory>
#include "QueryResult.h"
using namespace std;
class TextQuery
{
friend class QueryResult;
public:
TextQuery(ifstream&);
TextQuery();
void query(string);
protected:
private:
vector<string> lines;//保存每行文本
map<string, set<unsigned int>> wordsDic;//保存查找过单词的列表,这里set应该是这个指针类型,但是故意没有使用。
shared_ptr<QueryResult> p;
};
#endif
QueryResult.h
#ifndef __Query_Result_H__
#define __Query_Result_H__
#include "TextQuery.h"
using namespace std;
class QueryResult
{
public:
QueryResult();
void print(const map<string,set<vector<string>::size_type>>&, const vector<string>&,string);
protected:
private:
};
#endif
源文件
#include "TextQuery.h"
TextQuery::TextQuery(ifstream& f)
{
string line;
while (getline(f,line))
{
cout << line << endl;
lines.push_back(line);
}
p = make_shared<QueryResult>();
}
void TextQuery::query(string word)
{
for (vector<string>::size_type i = 0; i < lines.size(); i++)
{
istringstream s(lines.at(i));
string temp;
shared_ptr<set<vector<string>::size_type>> p;
if ((&wordsDic[word]) == nullptr)//假如此单词对应的行号列表为空
{
//这里是个陷阱,它存的是*p的拷贝,因为p在语句块结束时其内容就自动销毁了。
//注意正常情况下,这里应该存一个set指针(参考书上例子)。
p = make_shared<set<vector<string>::size_type>>();
wordsDic[word] = *p;
}
while (s>>temp)//读取这行的单词
{
if (temp == word)//假如查找到对应的单词
{
//插入行号
wordsDic[word].insert(i + 1);
}
}
}
//打印结果(故意使用相同名字p)
TextQuery::p->print(this->wordsDic,this->lines,word);
}
#include "QueryResult.h"
void QueryResult::print(const map<string, set<vector<string>::size_type>>& mp, const vector<string>& vec, string word)
{
cout << word << " occurs " << mp.at(word).size() << " times " << endl;
for (auto t : mp.at(word))
{
cout << "( line " << t << " ) " << vec.at(t - 1) << endl;
}
}
QueryResult::QueryResult()
{
}
#include <cstdlib>
#include <iostream>
#include "TextQuery.h"
#include "QueryResult.h"
using namespace std;
void runQueries(ifstream &infile)
{
TextQuery tq(infile);
while (true)
{
cout << "enter word to look for, or q to qiut: ";
string s;
if (!(cin >> s) || s == "q") break;
tq.query(s);
}
}
int main(int argc, char *argv[])
{
ifstream in("a.txt");
runQueries(in);
system("PAUSE");
return 0;
}