首页 > 代码库 > 《C++primer》v5 第9章 顺序容器 读书笔记 习题答案
《C++primer》v5 第9章 顺序容器 读书笔记 习题答案
9.1
(a)list。可以快速插入。
(b)deque。支持尾部快速插入和头部快速删除。
(c)vector或者deque。
9.2
list<deque<int> > l;
9.3
它的范围是该容器的第一个元素和尾元素之后。区间左闭右开。
9.4
#include<iostream>#include<algorithm>#include<cstdio>#include<list>#include<deque>#include<vector>using namespace std;bool find(pair<vector<int>::iterator,vector<int>::iterator> p,int val){ for(auto it=p.first;it!=p.second;++it) { if(*it==val) return true; } return false;}int main(){ vector<int> vec{1,3,19,2,0,5}; cout<<find(make_pair(vec.begin(),vec.end()),19); return 0;}
9.5
#include<iostream>#include<algorithm>#include<cstdio>#include<list>#include<deque>#include<vector>using namespace std;vector<int>::iterator find(pair<vector<int>::iterator,vector<int>::iterator> p,int val){ for(auto it=p.first;it!=p.second;++it) { if(*it==val) return it; } return p.second;}int main(){ vector<int> vec{1,3,19,2,0,5}; auto it=find(make_pair(vec.begin(),vec.end()),19); if(it==vec.end()) cout<<"No find!"<<endl; else cout<<"find "<<*it<<endl; return 0;}
9.6
list的迭代器没有重载<,因此会编译错误。应该将<换为!=。
9.7
整型?
9.8
string?value_type?
9.9
begin对于普通对象将返回只一个指向普通对象的迭代器,对于常量对象将返回一个指向常量对象的迭代器。
cbegin将返回一个指向常量对象的迭代器。
9.10
it1、it2:vector<int>::iterator
it3、it4:vector<int>::const_iterator
9.11
vector<int> a; vector<int> b{5,4,3,2,1}; vector<int> c={1,2,3,4,5,6}; vector<int> d(b); vector<int> e=c; vector<int> f(c.begin(),c.end());
9.12
创建一个容器为另一个容器的拷贝,两个容器的类型及其元素类型必须匹配。
当传递迭代器参数来拷贝一个范围时,不要求容器类型必须是相同的,而且新容器和原容器中的元素类型也可以不同,只要能将要拷贝的元素转换为要初始化的容器的元素类型即可。
9.13
通过传递迭代器来创建容器。
list<int> l {3,4,6,7}; vector<double> vec(l.begin(),l.end()); vector<int> vec2{1,2,3,4}; vector<double> vec3(vec2.begin(),vec2.end());
9.14
using namespace std;int main(){ list<char*> l{"abcde","xyz","qq"}; vector<string> vec(l.begin(),l.end()); for(auto i:vec) cout<<i<<endl; return 0;}
9.15
int main(){ vector<int> a{1,2,3},b{1,2,3}; if(a==b) cout<<"Yes!"<<endl; else cout<<"No!"<<endl; return 0;}
9.16
using namespace std;int compare(const list<int> &lhs,const vector<int> &rhs){ auto it=lhs.begin(); auto jt=rhs.begin(); while(it!=lhs.end()&&jt!=rhs.end()) { if(*it<*jt) return -1; else if(*it>*jt) return 1; it++; jt++; } if(it==lhs.end()&&jt==rhs.end()) return 0; else if(it==lhs.end()) return -1; else if(jt==rhs.end()) return 1;}int main(){ list<int>a {1,3}; vector<int> b {1,2,3}; cout<<compare(a,b)<<endl; return 0;}
9.17
必须重载了关于c1和c2的<运算符。
9.18
int main(){ string s; deque<string> dq; while(cin>>s) dq.push_back(s); for(auto i:dq) cout<<i<<endl; return 0;}
9.19
int main(){ string s; list<string> l; while(cin>>s) l.push_back(s); for(auto i:l) cout<<i<<endl; return 0;}
9.20
int main(){ list<int> l{123,1,2,3,5,12,4,6}; deque<int> a,b; for(list<int>::iterator it=l.begin();it!=l.end();++it) { if(*it%2==0) b.push_back(*it); else a.push_back(*it); } return 0;}
9.21
int main(){ vector<int> vec; vector<int>::iterator it=vec.begin(); int a; while(cin>>a) it=vec.insert(it,a); for(auto i:vec) cout<<i<<endl; return 0;}
理解的关键在于insert返回一个指向插入位置的迭代器。开始的时候需要插入到vec.begin()前面的位置,插入之后就返回这个位置的迭代器。下次插入的时候传入这个迭代器,会在它前面插入,再返回插入的位置。如此,即与push_front()相同。
9.22
insert操作使迭代器失效。
9.23
应该都是c[0]
int main(){ vector<int> c{8}; if(!c.empty()) { auto val=*c.begin(),val2=c.front(); auto last=c.end(); auto val3=*(--last); auto val4=c.back(); cout<<val<<" "<<val2<<" "<<val3<<" "<<val4<<endl; } return 0;}
9.24
int main(){ vector<int> c; c.at(0);//抛出异常 c[0]; c.front(); *c.begin(); return 0;}
只有使用at会抛出异常
9.25
如果相等则删除视为无效
9.26
int main(){ int ia[]= {0,1,1,2,3,5,8,13,21,55,89}; list<int> l(begin(ia),end(ia)); auto it=l.begin(); while(it!=l.end()) if(*it%2) it=l.erase(it); else ++it; for(auto it:l) cout<<it<<endl; cout<<"========="<<endl; vector<int> vec(begin(ia),end(ia)); auto jt=vec.begin(); while(jt!=vec.end()) if(*jt%2==0) jt=vec.erase(jt); else ++jt; for(auto it:vec) cout<<it<<endl; return 0;}
9.27
forward_list是单向列表因此有与其他容器不同的操作,尤其在删除方面。
它的删除是erase_after是删除给定迭代器后面的一个迭代器,返回删除位置后的一个迭代器。
before_begin()返回一个begin()前面的迭代器。
#include<forward_list>using namespace std;int main(){ int ia[]= {0,1,1,2,3,5,8,13,21,55,89}; forward_list<int> l(begin(ia),end(ia)); auto pre=l.before_begin(); auto cur=l.begin(); while(cur!=l.end()) { if(*cur%2) cur=l.erase_after(pre); else { pre=cur; ++cur; } } for(auto i:l) cout<<i<<endl; return 0;}
9.28
#include<forward_list>using namespace std;void solve(forward_list<string> &l,const string &a,const string &b){ auto pre=l.before_begin(); auto cur=l.begin(); while(cur!=l.end()) { if(*cur==a) { l.insert_after(cur,b); return ; } else { pre=cur; ++cur; } } l.insert_after(pre,b);}int main(){ string a="xxx",b="qq"; forward_list<string> l{"sdfs","xx","abc"}; solve(l,a,b); for(auto i:l) cout<<i<<endl; return 0;}
9.29
vec.resize(100)会将vec增大到100,多出75个位置将置0。
vec.resize(10)将把vec缩小至10。
9.30
如果是类类型,则必须提供一个默认构造函数。
9.31
list或forward_list的迭代器不支持+运算。
#include<list>using namespace std;int main(){ list<int> l {1,2,3,5,8,9,12}; auto it=l.begin(); while(it!=l.end()) { if(*it%2==0) { it=l.erase(it); } else { it=l.insert(it,*it); it++; it++; } } for(auto i:l) cout<<i<<endl; return 0;}
insert_after\erase_after返回一个插入位置的迭代器或删除位置后的一个位置的迭代器。
#include<forward_list>#include<list>using namespace std;int main(){ forward_list<int> l {1,2,3,5,8,9,12}; auto pre=l.before_begin(); auto cur=l.begin(); while(cur!=l.end()) { if(*cur%2==0) { cur=l.erase_after(pre); } else { cur=l.insert_after(cur,*cur); pre=cur; ++cur; } } for(auto i:l) cout<<i<<endl; return 0;}
9.32
不合法。
后面iter++是无意义的。该insert最终返回一个在iter位置前的迭代器。
9.33
如果不将insert的结果赋给begin将导致迭代器失效!
9.34
感觉此代码有错。对于奇数情况将导致死循环。
将奇数翻倍。
using namespace std;int main(){ vector<int> l {1,2,3,5,8,9,12}; auto begin=l.begin(); while(begin!=l.end()) { if(*begin%2) { begin=l.insert(begin,*begin); ++begin; } ++begin; } for(auto i:l) cout<<i<<endl; return 0;}
9.35
capacity是当前vector可容纳的最大元素数量
size是当前vector已经容纳的元素数量
9.36
不可能
9.37
list不支持随机访问因此内存不是连续储存的?
9.38
如果新加入元素后元素数量大于最大容量,将把最大容量扩大1倍。
9.39
向svec中添加元素。最后把svec大小变为原来的3/2。
9.40
略
9.41
int main(){ vector<char> vec{‘a‘,‘b‘,‘c‘,‘d‘}; string s(vec.begin(),vec.end()); cout<<s<<endl; return 0;}
9.42
int main(){ vector<char> vec; char a; while(cin>>a) vec.push_back(a); string s(vec.begin(),vec.end()); cout<<s<<endl; return 0;}
9.43、9.44、9.45、9.46
insert似乎是无返回值类型的。
这几个题暂略。。
《C++primer》v5 第9章 顺序容器 读书笔记 习题答案