码迷,mamicode.com
首页 > 编程语言 > 详细

《C++primer》v5 第9章 顺序容器 读书笔记 习题答案

时间:2014-08-29 18:01:48      阅读:396      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   os   使用   io   ar   for   div   

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章 顺序容器 读书笔记 习题答案

标签:style   blog   color   os   使用   io   ar   for   div   

原文地址:http://www.cnblogs.com/kkkwjx/p/3938582.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!