C++基础---容器

容器

在C++中,容器是用于存储和组织数据的数据结构。C++标准库提供了多种容器类型,每种类型都具有不同的特性和用途。以下是C++中常用的一些容器类型:

  1. 数组 (Array):数组是一种简单的容器类型,用于存储具有相同类型的一组元素。数组的大小在创建时确定,并且无法动态调整。

  2. 向量 (Vector):向量是一个动态数组,可以根据需要自动调整大小。它提供了在尾部高效添加和删除元素的操作,并且支持随机访问。

  3. 列表 (List):列表是一个双向链表,它允许在任意位置高效插入和删除元素。但是,对于随机访问来说效率较低。

  4. 队列 (Queue):队列是一种先进先出(FIFO)的数据结构,它允许在尾部添加元素,在头部删除元素。

  5. 栈 (Stack):栈是一种后进先出(LIFO)的数据结构,它允许在顶部添加和删除元素。

  6. 集合 (Set):集合是一组唯一元素的容器,不允许重复。可以用于高效地查找、插入和删除元素。

  7. 映射 (Map):映射是一种键值对的容器,每个键关联一个值。可以通过键快速查找、插入和删除对应的值。

  8. 迭代器 (Iterator):迭代器是用于遍历容器中元素的对象,可以以统一的方式访问容器中的元素。

这只是C++中一些常见的容器类型,C++标准库还提供了其他更多的容器类型和算法。你可以根据具体的需求选择适合的容器类型来存储和操作数据。

数组(array)

在C++中,数组(Array)是一种用于存储多个相同类型元素的数据结构。数组提供了一种连续的内存空间来存储元素,并使用索引来访问和操作这些元素

性质
  • 长度大小固定,且不能修改了
  • 所有元素是同一类型
  • 元素在内存中是连续的
    • 声明array ,内存中会分配一块区域来存储
    • 可以使用存储的索引位置来获取元素(从0开始,最后一个元素索引为size-1)
    • 不检查是否超出区域(超出长度获取元素可能报错)
创建一个整形的数组

在定义数组时要先进行初始化

int hend[4] = {5,6,7,8};//定义完成
int ages[7] = {10,2}; //定义了长度为10个的数组,但是只对前面2个进行初始化,其他的都为0
int agele[] = {2,34,1,4,23,14}//不用写几个,会自动知道,

进行下标访问的时候

hend[2]//访问数组为hend下标为2的数

创建一个数组 数组的类型 数组的变量[ 多少个数组]
创建数组及赋值 int 变量[3] = {3个自定义元素}

不可以这样赋值,如下列:

int hend[4] = {5,6,7,8};//:定义完成
hand  =  heand  //:不能定义后,在进行赋值。
hend[4] = {5,6,8,9}//:也不能定义以后在fu

显示类型的内存大小函数

sizeof("%对应的占位符号"&对应的变量)

计算数组里面多少个元素

列如:short things[] = {1,5,3,8};

int num_elememts = sizeof things / sizeof (short);

数组的初始化

如:

unsigned int counts[10] = {};// 全部初始化为0。
float balances[100]  {};// 全部初始化为0。

数组初始化禁止缩窄转换,要类型一样的。

如:long plifs[] = {25,92,3.0};这里的3.0是浮点数,转换成整数是要缩窄转换的,即使浮点数后面小数点为0,也不能通过编译。

简单的示例代码

#include 

int main() {
    // 声明一个整数数组并初始化
    int numbers[5] = {1, 2, 3, 4, 5};

    // 访问数组元素
    std::cout << "数组的第一个元素:" << numbers[0] << std::endl;

    // 修改数组元素
    numbers[2] = 10;

    // 遍历数组并输出元素
    std::cout << "数组中的元素:";
    for (int i = 0; i < 5; ++i) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    // 计算数组元素的总和
    int sum = 0;
    for (int i = 0; i < 5; ++i) {
        sum += numbers[i];
    }
    std::cout << "数组元素的总和:" << sum << std::endl;

    return 0;
}

在C++中,向量(Vector)

是一种动态数组,属于标准模板库(Standard Template Library,STL)的一部分。它提供了在运行时动态调整大小的功能,并提供了许多有用的成员函数和操作来方便地管理元素。

声明向量
#include 
using namespce std;
vector <char> vowels (5);//构造函数初始化方法,需要五个位置
vector <int> student_scores (10);//大小为10,与array不同,这10个数字会自动初始化为0
向量的初始化
vector <char> vowels ("a","s","d","f","g");
vector <int> student_scores (1,2,3,4,5,6);
vector <double> hi_scores (366,33.0);//长度为366,初始值为37.0


使用向量之前,需要包含 `<vector>` 头文件。下面是一个简单的示例代码,演示如何使用向量:

```cpp
#include 
#include 

int main() {
    // 创建一个整数向量
    std::vector<int> numbers;

    // 向向量中添加元素
    numbers.push_back(1);
    numbers.push_back(2);
    numbers.push_back(3);

    // 访问和修改向量中的元素
    std::cout << "第一个元素:" << numbers[0] << std::endl;
    numbers[1] = 5;

    // 遍历向量并输出元素
    std::cout << "向量中的元素:";
    for (int i = 0; i < numbers.size(); i++) {
        std::cout << numbers[i] << " ";
    }
    std::cout << std::endl;

    // 清空向量
    numbers.clear();

    // 检查向量是否为空
    if (numbers.empty()) {
        std::cout << "向量为空" << std::endl;
    }

    return 0;
}

在C++中,列表(List)

是另一种常见的容器,它也属于标准模板库(STL)的一部分。列表是一个双向链表,它允许在任意位置高效地插入和删除元素。

使用列表之前,需要包含 头文件。下面是一个简单的示例代码,演示如何使用列表:

#include 
#include 

int main() {
    // 创建一个整数列表
    std::list<int> numbers;

    // 向列表中添加元素
    numbers.push_back(1);
    numbers.push_back(2);
    numbers.push_back(3);

    // 在列表的开头插入一个元素
    numbers.push_front(0);

    // 遍历列表并输出元素
    std::cout << "列表中的元素:";
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 在列表中查找特定元素
    int target = 2;
    auto it = std::find(numbers.begin(), numbers.end(), target);
    if (it != numbers.end()) {
        std::cout << "找到了元素 " << target << std::endl;
    } else {
        std::cout << "未找到元素 " << target << std::endl;
    }

    // 删除列表中的元素
    numbers.remove(2);

    // 检查列表是否为空
    if (numbers.empty()) {
        std::cout << "列表为空" << std::endl;
    }

    return 0;
}

在C++中,队列(Queue)

是一种先进先出(First-In-First-Out,FIFO)的数据结构,用于存储和管理元素。队列通常用于实现任务调度、广度优先搜索等场景。

使用队列之前,需要包含 头文件。下面是一个简单的示例代码,演示如何使用队列:

#include 
#include 

int main() {
    // 创建一个整数队列
    std::queue<int> numbers;

    // 向队列中添加元素
    numbers.push(1);
    numbers.push(2);
    numbers.push(3);

    // 访问队列中的元素
    std::cout << "队列的第一个元素:" << numbers.front() << std::endl;

    // 遍历队列并输出元素
    std::cout << "队列中的元素:";
    while (!numbers.empty()) {
        std::cout << numbers.front() << " ";
        numbers.pop();
    }
    std::cout << std::endl;

    // 检查队列是否为空
    if (numbers.empty()) {
        std::cout << "队列为空" << std::endl;
    }

    return 0;
}

栈(Stack)

是一种常见的数据结构,它遵循后进先出(Last-In-First-Out,LIFO)的原则。栈通常用于处理函数调用、表达式求值、内存管理等方面。

在C++中,可以使用标准模板库(STL)中的 std::stack 类来实现栈。下面是一个简单的示例代码,演示如何使用栈:

#include 
#include 

int main() {
    // 创建一个整数栈
    std::stack<int> numbers;

    // 向栈中压入元素
    numbers.push(1);
    numbers.push(2);
    numbers.push(3);

    // 访问栈顶元素
    std::cout << "栈顶元素:" << numbers.top() << std::endl;

    // 遍历栈并输出元素
    std::cout << "栈中的元素:";
    while (!numbers.empty()) {
        std::cout << numbers.top() << " ";
        numbers.pop();
    }
    std::cout << std::endl;

    // 检查栈是否为空
    if (numbers.empty()) {
        std::cout << "栈为空" << std::endl;
    }

    return 0;
}

在这个示例中,我们首先包含了 头文件,并创建了一个名为 numbers 的整数栈。然后,我们使用 push() 函数将元素压入栈中。通过使用 top() 函数,我们可以访问栈顶元素。通过使用 pop() 函数,我们可以弹出栈顶元素。我们还使用 empty() 函数检查栈是否为空。

栈还提供了其他一些常用的成员函数,例如 size() 函数用于获取栈的大小。

集合(Set)

是一种用于存储不重复元素的数据结构。集合提供了一些常见的数学操作,例如并集、交集和差集,以及判断元素是否存在于集合中的功能。

在C++中,可以使用标准模板库(STL)中的 std::setstd::unordered_set 类来实现集合。std::set 实现了有序集合,而 std::unordered_set 实现了无序集合。

下面是一个简单的示例代码,演示如何使用 std::set 来操作集合:

#include 
#include 

int main() {
    // 创建一个整数集合
    std::set<int> numbers;

    // 向集合中插入元素
    numbers.insert(1);
    numbers.insert(2);
    numbers.insert(3);

    // 检查元素是否存在于集合中
    if (numbers.count(2) > 0) {
        std::cout << "元素2存在于集合中" << std::endl;
    }

    // 遍历集合并输出元素
    std::cout << "集合中的元素:";
    for (const auto& num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    // 从集合中移除元素
    numbers.erase(2);

    // 检查集合是否为空
    if (numbers.empty()) {
        std::cout << "集合为空" << std::endl;
    }

    return 0;
}

在这个示例中,我们首先包含了 头文件,并创建了一个名为 numbers 的整数集合。然后,我们使用 insert() 函数向集合中插入元素。通过使用 count() 函数,我们可以检查元素是否存在于集合中。通过使用范围-based for 循环,我们可以遍历集合并输出元素。我们还使用 erase() 函数从集合中移除元素。最后,我们使用 empty() 函数检查集合是否为空。

std::unordered_set 的用法与 std::set 类似,但不保持元素的顺序,并且在插入和查找操作上具有更快的平均时间复杂度。

映射(Map)

是一种将键(Key)与值(Value)关联起来的数据结构,也被称为字典(Dictionary)或关联数组(Associative Array)。映射提供了一种快速查找和访问值的方式,类似于现实生活中的字典,通过查找键可以找到对应的值。

在C++中,可以使用标准模板库(STL)中的 std::mapstd::unordered_map 类来实现映射。std::map 实现了有序映射,而 std::unordered_map 实现了无序映射。

下面是一个简单的示例代码,演示如何使用 std::map 来操作映射:

#include 
#include 

int main() {
    // 创建一个字符串到整数的映射
    std::map<std::string, int> ages;

    // 插入键值对到映射中
    ages["Alice"] = 25;
    ages["Bob"] = 30;
    ages["Charlie"] = 35;

    // 访问映射中的值
    std::cout << "Bob的年龄:" << ages["Bob"] << std::endl;

    // 遍历映射并输出键值对
    std::cout << "映射中的键值对:";
    for (const auto& entry : ages) {
        std::cout << entry.first << "=" << entry.second << " ";
    }
    std::cout << std::endl;

    // 检查键是否存在于映射中
    if (ages.count("Alice") > 0) {
        std::cout << "Alice存在于映射中" << std::endl;
    }

    // 从映射中移除键值对
    ages.erase("Charlie");

    // 检查映射是否为空
    if (ages.empty()) {
        std::cout << "映射为空" << std::endl;
    }

    return 0;
}

在这个示例中,我们首先包含了 头文件,并创建了一个名为 ages 的字符串到整数的映射。然后,我们使用键值对的方式将元素插入映射中。通过使用键来访问映射中的值,我们可以通过 ages["Bob"] 获取到 Bob 的年龄。通过使用范围-based for 循环,我们可以遍历映射并输出键值对。我们还使用 count() 函数检查键是否存在于映射中,并使用 erase() 函数从映射中移除键值对。最后,我们使用 empty() 函数检查映射是否为空。

std::unordered_map 的用法与 std::map 类似,但不保持键的顺序,并且在插入和查找操作上具有更快的平均时间复杂度。

迭代器(Iterator)

是一种用于遍历容器中元素的对象。它提供了一种统一的方式来访问容器中的元素,而不需要了解容器的内部结构。迭代器可以被用于访问容器中的元素、进行元素的修改和删除操作,以及在容器中插入新的元素。

在C++中,标准模板库(STL)的容器类(如 std::vectorstd::liststd::setstd::map 等)都提供了迭代器的支持。通过使用迭代器,你可以遍历容器并访问容器中的元素。

下面是一个简单的示例代码,演示如何使用迭代器来遍历 std::vector 容器:

#include 
#include 

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用迭代器遍历容器并输出元素
    std::cout << "容器中的元素:";
    for (std::vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

在这个示例中,我们首先包含了 头文件,并创建了一个名为 numbersstd::vector 容器。然后,我们使用迭代器来遍历容器并输出元素。numbers.begin() 返回指向容器第一个元素的迭代器,numbers.end() 返回指向容器最后一个元素之后位置的迭代器。我们使用循环来遍历迭代器,通过 *it 来访问迭代器指向的元素。

除了 std::vector,其他容器类(如 std::liststd::setstd::map 等)也提供类似的迭代器操作方式。

需要注意的是,C++11 引入了范围-based for 循环,使得遍历容器变得更加简洁。上面示例中的循环也可以使用范围-based for 循环来实现:

for (const auto& num : numbers) {
    std::cout << num << " ";
}

你可能感兴趣的:(#,C++基础,c++)