首页 > 代码库 > 《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章 顺序容器 读书笔记 习题答案