C++ Primer第5版 习题答案 第九章

目录

第九章 顺序容器

9.2 容器库概况

9.2.7 关系运算符(9.15 ~ 9.17)

9.3 顺序容器操作

9.3.1 向顺序容器添加元素(9.18 ~ 9.22)

9.3.2 访问元素 (9.23 ~ 9.24)

9.3.3 删除元素(9.25 ~ 9.26)

9.3.4 特殊的forward_list操作 (9.27 ~ 9.28)

9.3.5 改变容器大小 (9.29 ~ 9.30)

9.3.6 容器操作可能使迭代器失效 (9.31 ~ 9.35)

9.4 vector对象是如何增长的

未完待续


工作的间隙看的,所以输出比较慢,希望能巩固基础,再往后深入。

一直有参考这位同学的blog的答案:C++Primer第五版——习题答案+详解(完整版)_MISAYAONE的博客-CSDN博客,不过好像这位同学看的很快有很一些些不是很正确,看评论也有都一一修正。

这个答案也是自己看书然后输出的,也可能有问题,如果有发现什么问题,欢迎评论一起讨论!!

默认大家都有了第5版的纸质书或电子书,这里就只记录题号和答案(其实对原书的截图有点侵犯版权的感觉,狗头保命)

第九章 顺序容器

9.2 容器库概况

9.2.7 关系运算符(9.15 ~ 9.17)

9.15:

bool IsTwoVectorEqual(const vector<int>& a, const vector<int>& b) {
    return a == b;
}

9.16:

bool IsVectorAndListEqual(const vector<int>& v, const list<int>& l) {
    if(v.size() != l.size())
        return false;
    auto v_ite = v.begin();
    auto l_ite = l.begin();
    for(v_ite, l_ite; v_ite != v.end(); v_ite++, l_ite++) {
        if(*v_ite != *l_ite)
            return false;
    }
    return true;
}

9.17:

只有当其元素类型也定义了相应的比较运算符时,才可以使用关系运算符来比较两个容器。

9.3 顺序容器操作

9.3.1 向顺序容器添加元素(9.18 ~ 9.22)

9.18:

string str;
deque<string> dq;
while(cin >> str)
    dq.push_back(str);
for(auto iter = dq.begin(); iter != dq.end(); iter++)
    cout << *iter << endl;

9.19:

string str;
list<string> lst;
while(cin >> str)
    lst.push_back(str);
for(auto iter = lst.begin(); iter != lst.end(); iter++)
    cout << *iter << endl;

9.20:

list<int> lin{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
deque<int> dq1;
deque<int> dq2;
for(const auto& val : lin) {
    if(val % 2 == 0)
        dq1.push_back(val);
    else
        dq2.push_back(val);
}

9.21:

可以将元素插入到vector的开始位置。

9.22:

vector<int>::iterator iter = iv.begin(), mid = iv.begin() + iv.size() / 2;
while(iter != mid) {
    if(*iter == some_val)
        iv.insert(iter, 2 * some_val);
    iter++;
}

9.3.2 访问元素 (9.23 ~ 9.24)

9.23:

都是这唯一一个元素的值。

9.24:

at: out_of_range

下表运算符: 未定义 溢出

front: 未定义 溢出

begin: 访问空指针 未定义 溢出

9.3.3 删除元素(9.25 ~ 9.26)

9.25:

elem1和elem2相等,则不会删除任何元素,返回尾后迭代器。

elem2是尾后迭代器,则删除从elem1到容器末尾的所有元素,返回尾后迭代器。

elem1和elem2都是尾后迭代器,则不会删除任何元素,返回尾后迭代器。

list<int> lst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
auto elem1 = lst.begin();
auto elem2 = lst.begin();
auto elem3 = lst.erase(elem1, elem2);
cout << (elem3 == lst.begin()) << endl;
for(const auto& val : lst)
    cout << val << " ";
cout << endl;

lst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
elem1 = lst.begin();
elem2 = lst.end();
elem3 = lst.erase(elem1, elem2);
cout << (elem3 == lst.end()) << endl;
for(const auto& val : lst)
    cout << val << " ";
cout << endl;

lst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
elem1 = lst.end();
elem2 = lst.end();
elem3 = lst.erase(elem1, elem2);
cout << (elem3 == lst.end()) << endl;
for(const auto& val : lst)
    cout << val << " ";
cout << endl;

9.26:

int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
vector<int> v(ia, ia + sizeof(ia) / sizeof(int));
list<int> lst(ia, ia + sizeof(ia) / sizeof(int));
auto it = v.begin();
while(it != v.end()) {
    if(*it % 2 == 0)
        it = v.erase(it);
    else
        it++;
}
auto lit = lst.begin();
while(lit != lst.end()) {
    if(*lit % 2 != 0)
        lit = lst.erase(lit);
    else
        lit++;
}
cout << "vector: ";
for(const auto& val : v)
    cout << val << " ";
cout << endl;
cout << "list: ";
for(const auto& val : lst)
    cout << val << " ";
cout << endl;

9.3.4 特殊的forward_list操作 (9.27 ~ 9.28)

9.27:

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(const auto& val : flst) {
    cout << val << " ";
}
cout << endl;

9.28:

void FindAndInsertString(forward_list<string>& flst, const string& str1, const string& str2) {
    auto prev = flst.before_begin();
    auto curr = flst.begin();
    while(curr != flst.end()) {
        if(*curr == str1) {
            flst.insert_after(curr, str2);
            break;
        }
        prev = curr;
        curr++;
    }
    if(curr == flst.end()) {
        flst.insert_after(prev, str2);
    }
}

9.3.5 改变容器大小 (9.29 ~ 9.30)

9.29:

vec.resize(100)会将75个默认元素添加到vec中,vec.resize(10)会从vec末尾删除90个元素。

9.30:

如果容器保存的是类类型元素,则元素类型必须提供一个默认构造函数。

9.3.6 容器操作可能使迭代器失效 (9.31 ~ 9.35)

9.31:

list、forward_list的迭代器不能直接+2,forward_list无insert和erase方法,只有insert_after和eras_after这两个方法。

list<int> lst = {0,1,2,3,4,5,6,7,8,9};
auto iter = lst.begin();
while(iter != lst.end()) {
    if(*iter % 2) {
        lst.insert(iter, *iter);
        iter++;
    }
    else
        iter = lst.erase(iter);
}
for(const auto& v : lst)
    cout << v << " ";
cout << endl;

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.insert_after(curr, *curr);
        prev = curr;
        curr++;
    }
    else
        curr = flst.erase_after(prev);
}
for(const auto& v : flst)
    cout << v << " ";
cout << endl;
}

9.32:

不合法,因为赋值运算符左右两端都用到了iter,并且右侧的运算对象还改变了iter的值,所以该赋值语句是未定义的,运算对象可按任意顺序求值,见书133页。

9.33:

会访问失效指针,未定义行为。

vector<int> vi = {0,1,2,3,4,5,6,7,8,9};
auto iter = vi.begin();
while(iter != vi.end()) {
    ++iter;
    vi.insert(iter, 42);
    ++iter;
}
for(const auto& v : vi)
    cout << v << " ";
cout << endl;

9.34:

因为代码是对奇数复制插入到这个奇数的前面,iter返回的是插入元素的迭代器,所以即便后来向后移一位,还是奇数,陷入无限循环中。还有缺少花括号。

9.4 vector对象是如何增长的

9.35:

size指已经保存的元素数目;capacity是在不分配新的内存空间的前提下最多可以保存多少元素。

9.36:

不可能。

9.37:

list存储元素的内存不是连续的且不需要提前分配内存,array的所占内存大小是固定的。

9.38:

vector<int> ivec;
cout << " ivec: size: " << ivec.size()
    << " capacity: " << ivec.capacity() << endl;
for(vector<int>::size_type ix = 0; ix != 24; ++ix) {
    ivec.push_back(ix);
    cout << " ivec: size: " << ivec.size()
        << " capacity: " << ivec.capacity() << endl;
}

vector实现采用的策略似乎是每次需要分配新内存空间时,将当前容量翻倍。

9.39:

先给vector分配1024的容量,然后不停读取string直到结束,再自动填充vector当前拥有元素数量的一半的空字符串到当前vector中。

9.40:

void func(int num) {
    vector<string> svec;
    svec.reserve(1024);
    for(int i = 0; i < num; i++)
        svec.push_back("str");
    svec.resize(svec.size() + svec.size() / 2);
    cout << "读入" << num << "词, ";
    cout << " svec: size: " << svec.size()
          << " capacity: " << svec.capacity() << endl;
}
func(256); func(512); func(1000); func(1048);

未完待续

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值