C++

C++ 知识量:19 - 82 - 316

9.1 顺序容器><

顺序容器概述- 9.1.1 -

C++中的顺序容器是一种线性容器,它按照元素在内存中的顺序进行存储,并保持元素之间的相对顺序。顺序容器通常使用数组或指针来实现,其操作主要包括添加、删除、查找和修改元素等。

顺序容器具有以下特点:

  • 元素在内存中连续存储,可以随机访问。

  • 元素之间的相对顺序保持不变,即插入或删除元素不会改变其他元素的相对位置。

  • 可以通过下标运算符或迭代器访问元素。

  • 通常具有一些常用的操作,如push_back()、pop_back()、erase()、insert()等。

C++标准库中提供了多种顺序容器,包括vector、deque、list、set、multiset、map、multimap等。这些容器在实现上有所不同,但都具有上述特点。使用顺序容器可以方便地进行数据的存储和操作,提高程序的效率和可读性。

容器库概览- 9.1.2 -

C++标准库提供了多种容器,这些容器可以用来存储和操作各种类型的数据。以下是对C++容器库的概览:

1. 序列容器:

  • array:静态的、连续数组,类似于C语言中的数组。

  • vector:动态的、连续数组,其长度可以随着插入或者移除的元素而变化。

  • deque:双端队列,可以在头部和尾部进行插入和删除操作。

  • list:双向链表,可以进行任意的插入和删除操作。

2. 关联容器:

  • set:集合,只包含唯一的元素,根据元素的键值进行排序。

  • multiset:多重集合,包含可以重复的元素,根据元素的键值进行排序。

  • map:关联数组,将键值映射到对应的值。

  • multimap:多重关联数组,将键值映射到多个值。

3. 无序关联容器:

  • unordered_set:无序集合,只包含唯一的元素,不保证元素的排序。

  • unordered_multiset:无序多重集合,包含可以重复的元素,不保证元素的排序。

  • unordered_map:无序关联数组,将键值映射到对应的值,不保证元素的排序。

  • unordered_multimap:无序多重关联数组,将键值映射到多个值,不保证元素的排序。

4. 容器适配器:

  • stack:栈,后进先出(LIFO)的数据结构。

  • queue:队列,先进先出(FIFO)的数据结构。

  • priority_queue:优先队列,根据元素的优先级进行操作。

迭代器- 9.1.3 -

C++中的迭代器是一种用于遍历容器元素的对象,它们提供了访问容器内部元素的方式,类似于指针的作用。迭代器可以在容器的任何位置进行迭代,并可以用于对容器进行搜索、排序等操作。

C++标准库中的容器都提供了迭代器,每个容器都有自己的迭代器类型,例如vector的迭代器是vector::iterator,set的迭代器是set::iterator等。

迭代器可以按照以下方式使用:

1. 使用迭代器遍历容器中的所有元素。例如,可以使用vector::begin()和vector::end()返回的迭代器来遍历vector中的所有元素:

std::vector<int> v = {1, 2, 3, 4, 5};  
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {  
    std::cout << *it << " ";  
}

输出:1 2 3 4 5

2. 使用迭代器在容器中进行搜索。例如,可以使用find()函数在vector中搜索特定的元素:

std::vector<int> v = {1, 2, 3, 4, 5};  
std::vector<int>::iterator it = std::find(v.begin(), v.end(), 3);  
if (it != v.end()) {  
    std::cout << "Found 3 at position " << std::distance(v.begin(), it) << std::endl;  
} else {  
    std::cout << "3 not found" << std::endl;  
}

输出:Found 3 at position 2

3. 使用迭代器在容器中进行排序。例如,可以使用sort()函数对vector进行排序:

std::vector<int> v = {5, 2, 4, 1, 3};  
std::sort(v.begin(), v.end());  
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {  
    std::cout << *it << " ";  
}


容器类型成员- 9.1.4 -

C++标准库提供了许多容器类型,每个容器类型都有一些成员函数,可以用来对其进行操作。以下是一些常见的C++容器类型及其成员函数:

1. vector:

  • size():返回vector中元素的数量。

  • empty():判断vector是否为空。

  • push_back():在vector的末尾插入一个元素。

  • pop_back():删除vector的最后一个元素。

  • begin():返回指向vector第一个元素的迭代器。

  • end():返回指向vector最后一个元素之后位置的迭代器。

2. deque:

  • size():返回deque中元素的数量。

  • empty():判断deque是否为空。

  • push_front():在deque的前端插入一个元素。

  • pop_front():删除deque的第一个元素。

  • begin():返回指向deque第一个元素的迭代器。

  • end():返回指向deque最后一个元素之后位置的迭代器。

3. list:

  • size():返回list中元素的数量。

  • empty():判断list是否为空。

  • push_back():在list的末尾插入一个元素。

  • pop_back():删除list的最后一个元素。

  • push_front():在list的前端插入一个元素。

  • pop_front():删除list的第一个元素。

  • begin():返回指向list第一个元素的迭代器。

  • end():返回指向list最后一个元素之后位置的迭代器。

4. set:

  • size():返回set中元素的数量。

  • empty():判断set是否为空。

  • insert():向set中插入一个元素。

  • *erase() :从set中删除一个元素。

  • begin():返回指向set第一个元素的迭代器。

  • end():返回指向set最后一个元素之后位置的迭代器。

5. map:

  • size():返回map中元素的数量。

  • empty():判断map是否为空。

  • insert():向map中插入一个键值对。

  • *erase() :从map中删除一个键值对。

  • find():在map中查找指定的键值,并返回指向该键值的迭代器。

  • begin():返回指向map第一个键值对的迭代器。

  • end():返回指向map最后一个键值对之后位置的迭代器。

容器定义和初始化- 9.1.5 -

在C++中,可以使用标准模板库(STL)提供的容器类型来存储和管理数据。以下是一些常见的容器类型及其定义和初始化方法:

1. vector:

// 定义一个vector<int>类型的容器      
std::vector<int> v; // 空vector      
std::vector<int> v = {1, 2, 3, 4, 5}; // 初始化vector并添加元素

2. deque:

// 定义一个deque<int>类型的容器      
std::deque<int> d; // 空deque      
std::deque<int> d = {1, 2, 3, 4, 5}; // 初始化deque并添加元素

3. list:

// 定义一个list<int>类型的容器      
std::list<int> l; // 空list      
std::list<int> l = {1, 2, 3, 4, 5}; // 初始化list并添加元素

4. set:

// 定义一个set<int>类型的容器      
std::set<int> s; // 空set      
std::set<int> s = {1, 2, 3, 4, 5}; // 初始化set并添加元素

5. map:

// 定义一个map<string, int>类型的容器      
std::map<std::string, int> m; // 空map      
std::map<std::string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}}; // 初始化map并添加键值对

容器的赋值- 9.1.6 -

C++中的容器赋值有多种方式,以下是几种常见的赋值方式:

1. 使用赋值运算符进行赋值:

std::vector<int> v1 = {1, 2, 3};    
std::vector<int> v2;    
v2 = v1; // 使用赋值运算符将v1赋值给v2

2. 使用容器类的成员函数assign进行赋值:

std::vector<int> v;    
v.assign({1, 2, 3}); // 使用assign函数将{1, 2, 3}赋值给v

3. 使用容器类的成员函数insert进行赋值:

std::vector<int> v;    
v.insert(v.begin(), 1); // 在vector的开头插入元素1      
v.insert(v.end(), {2, 3}); // 在vector的末尾插入元素2和3

4. 使用容器类的成员函数erase进行赋值:

std::vector<int> v = {1, 2, 3};    
v.erase(v.begin() + 1); // 删除vector中的第二个元素,将剩余元素重新赋值给v

注意:不同类型的容器赋值方式可能有所不同,需要根据具体情况选择合适的赋值方式。

交换相同类型容器的内容- 9.1.7 -

要交换两个相同类型的容器内容,可以使用C++标准库中的std::swap()函数。该函数可以用于交换两个相同类型的容器,包括数组、向量、列表等。

下面是一个使用std::swap()函数交换两个向量容器的示例代码:

#include <iostream>  
#include <vector>  
  
int main() {  
    std::vector<int> v1 = {1, 2, 3};  
    std::vector<int> v2 = {4, 5, 6};  
      
    std::swap(v1, v2); // 交换两个向量的内容  
      
    std::cout << "v1: ";  
    for (int i : v1) {  
        std::cout << i << " ";  
    }  
    std::cout << std::endl;  
      
    std::cout << "v2: ";  
    for (int i : v2) {  
        std::cout << i << " ";  
    }  
    std::cout << std::endl;  
      
    return 0;  
}

输出结果为:

v1: 4 5 6    
v2: 1 2 3

可以看到,使用std::swap()函数交换两个向量的内容非常简单。同样的方法也适用于其他类型的容器,只需将容器类型和变量名替换即可。

获取容器的大小- 9.1.8 -

在C++中,可以使用标准模板库(STL)容器中的size()函数来获取容器的大小。

例如,如果有一个vector容器,可以像这样获取其大小:

#include <vector>  
#include <iostream>  
  
int main() {  
    std::vector<int> myVector = {1, 2, 3, 4, 5};  
    std::cout << "Size of myVector: " << myVector.size() << std::endl;  
    return 0;  
}

输出将会是:

Size of myVector: 5

同样,对于其他类型的容器,例如list、deque、set和map,也可以使用size()函数来获取它们的大小。

容器对关系运算符的支持- 9.1.9 -

C++ 的标准容器,如 std::vector, std::list, std::deque, std::set, std::map 等,都支持关系运算符(比较运算符),如 <, <=, >, >=, == 和 !=。这些运算符可以用于比较两个容器的大小。

例如,可以比较两个 std::vector 是否相等:

#include <vector>  
#include <iostream>  
  
int main() {  
    std::vector<int> v1 = {1, 2, 3};  
    std::vector<int> v2 = {1, 2, 3};  
    if (v1 == v2) {  
        std::cout << "v1 is equal to v2\n";  
    } else {  
        std::cout << "v1 is not equal to v2\n";  
    }  
    return 0;  
}

这段代码将输出 "v1 is equal to v2",因为两个向量的内容是相同的。

同样,也可以使用这些运算符来比较两个容器的大小。例如,可以比较两个 std::vector 的大小:

#include <vector>  
#include <iostream>  
  
int main() {  
    std::vector<int> v1 = {1, 2, 3};  
    std::vector<int> v2 = {4, 5, 6};  
    if (v1 < v2) {  
        std::cout << "v1 is less than v2\n";  
    } else if (v1 > v2) {  
        std::cout << "v1 is greater than v2\n";  
    } else {  
        std::cout << "v1 is equal to v2\n";  
    }  
    return 0;  
}

这段代码将输出 "v1 is less than v2",因为 v1 的大小小于 v2。