Chapter 9: Sequential Containers

本文详细探讨了C++中不同容器如list、deque、vector的特性及其适用场景,强调了迭代器在遍历和修改容器元素时的重要作用。通过多个练习题解析,阐述了迭代器的增删查改操作,以及如何使用迭代器进行容器间的转换。同时,讨论了容器的大小和容量管理,包括resize和reserve函数的使用。最后,提到了在实际编程中如何有效利用迭代器和容器操作提高代码效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Exercises Section 9.1

Ex9.1

a) list     可能涉及中间插入操作

b) deque    涉及头部删除,尾部插入
  
c) vector   没有更好的选择

Exercises Section 9.2

Ex9.2

list<deque<int>> lqint;

Exercises Section 9.2.1

Ex9.3

1. begin and end refer to elements of or one past the end of the same continer.
2. It is possible to reach end by repeatedly incrementing begin.

Ex9.4

bool func(vector<int>::iterator begin, vector<int>::iterator end, int value)
{
	for (; begin != end; ++begin)
    {
    	if ((*begin) == value)
        	return true;
    }
    return false;
}

Ex9.5

vector<int>::iterator func(vector<int>::iterator begin, vector<int>::iterator end, int value)
{
	for (; begin != end; ++begin)
    {
    	if ((*begin) == value)
            return begin;
    }
    return end; // 未找到
}

Ex9.6

// lst1 中没有元素,故而使用迭代器无效
list<int> lst1;
list<int>::iterator iter1 = lst1.begin(), iter2 = lst1.end();
while (iter1 < iter2) /* ... */

Exercises Section 9.2.2

Ex9.7

vector<int>::iterator 

Ex9.8

list<string>::iterator

Exercises Section 9.2.3

Ex9.9

begin 未被 const 修饰;cbegin 被 const 修饰

Ex9.10

vector<int> v1;
const vector<int> v2;
auto it1 = v1.begin(), it2 = v2.begin();	
auto it3 = v1.cbegin(), it4 = v2.cbegin();

it1 的类型为 vector<int>::iterator
it2 的类型为 vector<int>::const_iterator
it3 的类型为 vector<int>::const_iterator
it3 的类型为 vector<int>::const_iterator

Exercises Section 9.2.4

Ex9.11

vector<int> vec1(begin, end);
vector<int> vec2(vec1);
vector<int> vec3 = vec1;
vector<int> vec4{0, 1, 3, 4};
vector<int> vec5 = {0, 1, 3, 4};
vector<int> vec6(4, 1);

Ex9.12

takes a container: 必须保证两个容器类型一样且容器存储类型一样
takes two iterators: 迭代器指向的元素类型必须可以被要初始化的容器兼容

Ex9.13

#include<iostream>
#include<vector>
#include<list>

using namespace std;

int main()
{
    vector<int> vec1 = {1, 2, 3, 4};
    list<int> lst = {1, 2, 3, 4};
    vector<double> vec2(vec1.begin(), vec1.end());
    vector<double> vec3(lst.begin(), lst.end());

    for (auto it = vec2.begin(); it != vec2.end(); ++it)
        cout << *it << endl;
    for (auto it = vec3.begin(); it != vec3.end(); ++it)
        cout << *it << endl;   

    system("pause");
    return 0;
}

Exercises Section 9.2.5

Ex9.14

#include<iostream>
#include<vector>
#include<string>
#include<list>

using namespace std;

int main()
{
    list<char *> lst = {"Faker", "Rookie", "Uzi"};
    vector<string> vec(lst.begin(), lst.end());

    for (auto it = vec.begin(); it != vec.end(); ++it)
        cout << *it << endl;

    system("pause");
    return 0;
}

Exercises Section 9.2.7

Ex9.15

#include<iostream>
#include<vector>

using namespace std;

int main()
{
    vector<int> vec1 = {1, 2, 3, 4};
    vector<int> vec2 = {1, 2, 3};
    if (vec1 == vec2)
        cout << "Two vector are equal" << endl;
    else 
        cout << "Two vector are not equal" << endl;
    system("pause");
    return 0;
}

Ex9.16

#include<iostream>
#include<vector>
#include<list>

using namespace std;

int main()
{
    list<int> lst = {1, 2, 3, 4};
    vector<int> vec = {1, 2, 3};
    if (lst.size() != vec.size())
    {
        cout << "Not equal" << endl;
        system("pause");
        return 0;
    }
    auto it1 = lst.begin();
    auto it2 = vec.begin();
    for (; it1 != lst.end(); ++it1, ++it2)
    {
        if (*it1 != *it2)
        {
            cout << "Not equal" << endl;
            system("pause");
            return 0;
        }
    }
    cout << "Equal" << endl;
    system("pause");
    return 0;
}

Ex9.17

c1 和 c2 的容器类型必须一样且容器内存储的元素的类型也必须一样

Exercises Section 9.3.1

Ex9.18

#include<iostream>
#include<deque>
#include<string>

using namespace std;

int main()
{
    deque<string> dq;
    string word;
    while (cin >> word)
        dq.push_back(word);
    for (auto it = dq.begin(); it != dq.end(); ++it)
        cout << *it << " ";
    cout << endl;
    system("pause");
    return 0;
}

Ex9.19

#include<iostream>
#include<list>
#include<string>

using namespace std;

int main()
{
    string word;
    list<string> lst;
    while (cin >> word)
        lst.push_back(word);
    for (auto it = lst.begin(); it != lst.end(); ++it)
        cout << *it << " ";
    cout << endl;
    system("pause");
    return 0;
}

Ex9.20

#include<iostream>
#include<list>
#include<string>
#include<deque>

using namespace std;

int main()
{
    int value;
    list<int> lst;
    deque<int> even;
    deque<int> odd;
    while (cin >> value)
        lst.push_back(value);
    for (auto it = lst.begin(); it != lst.end(); ++it)
    {
        if (*it % 2 == 0)
            even.push_back(*it);
        else 
            odd.push_back(*it);
    }
    for (auto it = even.begin(); it != even.end(); ++it)
        cout << *it << " ";
    cout << endl;
    for (auto it = odd.begin(); it != odd.end(); ++it)
        cout << *it << " ";
    cout << endl;
    system("pause");
    return 0;
}

Ex9.21

其实就相当于在 vector 的头部插入元素

Ex9.22

	// iv is a vector of ints
    // iv.begin() 和 iv.size() 类型不一样,不能直接使用 + 符号
    // 修正: mid = iv.begin() + (iv.end() - iv.begin()) / 2;
    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);
    }

Exercises Section 9.3.2

Ex9.23

val1 = val2 = val3 = val4

Ex9.24

#include<iostream>
#include<vector>

using namespace std;

int main()
{
    vector<int> vec;
    cout << vec.at(0) << endl;
    cout << vec[0] << endl;
    cout << vec.front();
    cout << *vec.begin();
    system("pause");
    return 0;
}

Exercises Section 9.3.3

Ex9.25

当 elem1 = elem2 时,不会删除任何元素;
当 elem2 为 off-the-end 迭代器,会删除所有元素;
当 elem1 和 elem2 都为 off-the-end 迭代器,不会删除任何元素

Ex9.26

#include<iostream>
#include<vector>
#include<list>

using namespace std;

int main()
{   
    int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
    vector<int> v;
    list<int> l;
    for (int i = 0; i < sizeof(ia) / sizeof(ia[0]); ++i)
    {
        v.push_back(ia[i]);
        l.push_back(ia[i]);
    }
    auto it1 = v.begin();
    auto it2 = l.begin();
    while (it1 != v.end())
    {
        if (*it1 % 2 == 0)
            it1 = v.erase(it1);
        else
            ++it1;
    }
    for (auto it = v.begin(); it != v.end(); ++it)
        cout << *it << " ";
    cout << endl;
    while (it2 != l.end())
    {
        if (*it2 % 2)
            it2 = l.erase(it2);
        else 
            ++it2;
    }
    for (auto it = l.begin(); it != l.end(); ++it)
        cout << *it << " ";
    cout << endl;
    system("pause");
    return 0;
}

Exercises Section 9.3.4

Ex9.27

#include<iostream>
#include<forward_list>

using namespace std;

int main()
{   
    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 it = flst.begin(); it != flst.end(); ++it)
        cout << *it << " ";
    cout << endl;
    system("pause");
    return 0;
}

Ex9.28

void find_remove(forward_list<string> &flst, const string &s1, const string &s2)
{
    auto prev = flst.before_begin();
    auto curr = flst.begin();
    bool flag = false;
    while (curr != flst.end())
    {
        if (*curr == s1)
        {
            prev = curr;
            curr = flst.insert_after(prev, s2);
            flag = true;
        }
        else 
        {
            prev = curr;
            ++curr;
        }
    }
    if (flag == false)
        flst.insert_after(prev, s2);
} 

Exercises Section 9.3.5

Ex9.29

vector<int> vec(25, 1);
vec.resize(100);	// 将 vec 容量扩大到100,后面新增的 75 个元素值都为0
vec.resize(10);	// 将 vec 容量减小到 10,删除后面 90 个元素

Ex9.30

传入的单个参数值不能小于0

Exercises Section 9.3.6

Ex9.31

#include<iostream>
#include<forward_list>

using namespace std;

int main()
{   
    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 (auto it = flst.begin(); it != flst.end(); ++it)
        cout << *it << " ";
    cout << endl;
    system("pause");
    return 0;
}

Ex9.32

// 改成如下形式也可
iter = vi.insert(iter, *iter++);
++iter;

Ex9.33

如果不将 insert 函数返回的值赋给 begin,会发生错误

Ex9.34

// 会进行无限循环
    auto iter = vi.begin();
    while (iter != vi.end())
    {
        if (*iter % 2)
            iter = vi.insert(iter, *iter);
        ++iter;
    }
    
// 正确代码如下:
#include<iostream>
#include<vector>

using namespace std;

int main()
{   
    vector<int> vi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    auto iter = vi.begin();
    while (iter != vi.end())
    {
        if (*iter % 2)
        {
            iter = vi.insert(iter, *iter);
            ++iter;
        }
        ++iter;
    }
    for (auto it = vi.begin(); it != vi.end(); ++it)
        cout << *it << " ";
    cout << endl;
    system("pause");
    return 0;
}

Exercises Section 9.4

Ex9.35

size:	容器内元素的数量
capacity: 容器可容纳元素的最大数量

Ex9.36

容器的 capacity 不能小于 size 

Ex9.37

因为 list 和 array 都是有多少元素就分配多少存放元素的空间

Ex9.38

#include<iostream>
#include<vector>

using namespace std;

int main()
{   
    vector<int> ivec;
    cout << "ivec:szie = " << ivec.size() << " " << "ivec:capacity = " << ivec.capacity() << endl;
    for (auto i = 0; i != 24; ++i)
    {
        ivec.push_back(i);
    }
    cout << "ivec:szie = " << ivec.size() << " " << "ivec:capacity = " << ivec.capacity() << endl;
    while (ivec.size() != ivec.capacity())
        ivec.push_back(0);
    cout << "ivec:szie = " << ivec.size() << " " << "ivec:capacity = " << ivec.capacity() << endl;
    ivec.push_back(1);
    cout << "ivec:szie = " << ivec.size() << " " << "ivec:capacity = " << ivec.capacity() << endl;
    system("pause");
    return 0;
}

Ex9.39

    vector<string> svec;	// 一个存储 string 类型的 vector 容器
    svec.reserve(1024);		// 给该容器预分配 1024 的 capacity
    string word;			
    while (cin >> word)			// 将输入的 string 类型变量添加到容器中
        svec.push_back(word);	
    svec.resize(svec.size() + svec.size() / 2);	// 将容器内的元素数量变为 svec.size() + svec.size() / 2

Ex9.40

reads 256 words: capacity = 1024
reads 512 words: capacity = 1024
reads 1000 words: capacity = 2048
reads 1048 words: capacity = 2048

Exercises Section 9.5.1

Ex9.41

#include<iostream>
#include<vector>
#include<string>

using namespace std;

int main()
{   
    vector<char> vec = {'h', 'e', 'l', 'l', 'o'};
    string s(&vec[0], vec.size());
    cout << s << endl;
    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值