C++学习之STL

简介: C++学习之STL

C++ STL的概念

C++ STL(Standard Template Library,标准模板库)是C++标准库中的一个重要组成部分,提供了丰富的通用数据结构和算法。STL包含了多个容器(如vector、list、map等),迭代器(iterator)、算法(algorithm)等组件,可以帮助开发者更高效地进行数据处理和算法实现。

STL的主要概念包括:

  1. 容器(Containers):STL提供了多种容器,如vector(动态数组)、list(双向链表)、map(关联数组)等,用于存储不同类型的数据。
  2. 迭代器(Iterators):迭代器允许通过统一的方式遍历容器中的元素,从而实现对容器的操作。
  3. 算法(Algorithms):STL包含了大量的通用算法,如排序、查找、复制等,可以直接应用于各种容器,并且具有高效性能和可重用性。
  4. 函数对象(Function Objects):函数对象是可调用对象,类似于函数指针,用于在算法中执行特定操作。
  5. 适配器(Adapters):STL提供了对容器和迭代器的适配器,如stack(栈)、queue(队列)、priority_queue(优先队列)等。

实际上,STL为C++程序员提供了强大的工具集,可以大大简化数据处理和算法实现的过程,提高代码的可读性和可维护性。

C++ STL:vector存放内置数据类型

当使用STL的vector容器来存放内置数据类型时,可以根据需求选择不同的操作和功能。下面是一些常见的使用情况和相应的代码示例:

  1. 创建一个包含int类型的vector,并添加元素:
#include <iostream>
#include <vector>
int main() {
    std::vector<int> nums; // 创建一个存放int类型的vector
    nums.push_back(1); // 添加元素到vector尾部
    nums.push_back(2);
    nums.push_back(3);
    // 遍历打印所有元素
    for (int i = 0; i < nums.size(); i++) {
        std::cout << nums[i] << " ";
    }
    std::cout << std::endl;
    return 0;
}

输出结果为:1 2 3

  1. 在vector中查找指定值的元素:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};
    
    // 使用find算法在vector中查找指定值
    auto it = std::find(nums.begin(), nums.end(), 3);
    if (it != nums.end()) {
        std::cout << "元素找到了,位置为:" << std::distance(nums.begin(), it) << std::endl;
    } else {
        std::cout << "未找到指定元素" << std::endl;
    }
    
    return 0;
}

输出结果为:元素找到了,位置为:2

  1. 使用迭代器进行遍历和修改:
#include <iostream>
#include <vector>
int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};
    
    // 使用迭代器遍历和修改元素
    for (auto it = nums.begin(); it != nums.end(); ++it) {
        // 修改当前位置的元素值
        *it *= 2;
    }
    
    // 遍历打印修改后的元素
    for (const auto& num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

输出结果为:2 4 6 8 10

这些示例展示了在存放内置数据类型的vector中进行元素添加、查找和修改的常用操作。需要注意的是,vector的大小可变,可以根据需要动态地添加或删除元素。

C++ STL:vector存放自定义数据类型

当使用STL的vector容器存放自定义数据类型时,需要注意以下几个情况,并相应提供代码示例:

  1. 定义自定义数据类型:

首先,要定义一个自定义数据类型,可以通过定义一个结构体或者类来实现。例如,我们定义一个名为Person的结构体,包含姓名和年龄两个成员变量:

struct Person {
    std::string name;
    int age;
};
  1. 创建一个包含自定义数据类型的vector,并添加元素:
#include <iostream>
#include <vector>
struct Person {
    std::string name;
    int age;
};
int main() {
    std::vector<Person> persons; // 创建一个存放Person类型的vector
    Person p1{"Alice", 25}; // 创建并初始化一个Person对象
    persons.push_back(p1); // 添加到vector中
    persons.push_back({"Bob", 30}); // 可直接在push_back函数中创建并添加元素
    // 遍历打印所有人的姓名和年龄
    for (const auto& person : persons) {
        std::cout << "姓名: " << person.name << ", 年龄: " << person.age << std::endl;
    }
    return 0;
}

输出结果为:

姓名: Alice, 年龄: 25
姓名: Bob, 年龄: 30
  1. 在vector中查找指定值的元素:
#include <iostream>
#include <vector>
#include <algorithm>
struct Person {
    std::string name;
    int age;
};
int main() {
    std::vector<Person> persons = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 35}};
    // 使用find_if算法在vector中查找年龄大于等于30的人
    auto it = std::find_if(persons.begin(), persons.end(), [](const Person& p) {
        return p.age >= 30;
    });
    if (it != persons.end()) {
        std::cout << "找到年龄大于等于30的人,姓名:" << it->name << ", 年龄:" << it->age << std::endl;
    } else {
        std::cout << "未找到符合条件的人" << std::endl;
    }
    return 0;
}

输出结果为:找到年龄大于等于30的人,姓名:Bob, 年龄:30

  1. 使用迭代器进行遍历和修改:
#include <iostream>
#include <vector>
struct Person {
    std::string name;
    int age;
};
int main() {
    std::vector<Person> persons = {{"Alice", 25}, {"Bob", 30}, {"Charlie", 35}};
    // 使用迭代器遍历和修改元素
    for (auto& person : persons) {
        // 修改年龄
        person.age += 1;
    }
    // 遍历打印修改后的所有人的姓名和年龄
    for (const auto& person : persons) {
        std::cout << "姓名: " << person.name << ", 年龄: " << person.age << std::endl;
    }
    return 0;
}

输出结果为:

姓名: Alice, 年龄: 26
姓名: Bob, 年龄: 31
姓名: Charlie, 年龄: 36

这些示例展示了在存放自定义数据类型的vector中进行元素添加、查找和修改的常见操作。需要注意的是,自定义数据类型要重载适用于该类型的运算符,例如比较运算符等,以便在算法中使用。

C++ STL:容器嵌套容器

在STL中,容器嵌套容器是一种常见的数据结构设计方式。它允许我们在一个容器中存放另一个容器作为其元素。下面是几个常见的容器嵌套容器的示例:

  1. Vector嵌套vector:
#include <iostream>
#include <vector>
int main() {
    // 创建一个嵌套vector的容器
    std::vector<std::vector<int>> nestedVector;
    // 创建并添加第一个内层vector
    std::vector<int> innerVector1 = {1, 2, 3};
    nestedVector.push_back(innerVector1);
    // 创建并添加第二个内层vector
    std::vector<int> innerVector2 = {4, 5, 6};
    nestedVector.push_back(innerVector2);
    // 遍历打印所有元素
    for (const auto& innerVec : nestedVector) {
        for (const auto& num : innerVec) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}

输出结果为:

1 2 3 
4 5 6 
  1. Vector嵌套map:
#include <iostream>
#include <vector>
#include <map>
int main() {
    // 创建一个嵌套map的容器
    std::vector<std::map<std::string, int>> nestedVectorMap;
    // 创建并添加第一个内层map
    std::map<std::string, int> innerMap1 = {{"apple", 1}, {"banana", 2}};
    nestedVectorMap.push_back(innerMap1);
    // 创建并添加第二个内层map
    std::map<std::string, int> innerMap2 = {{"orange", 3}, {"grape", 4}};
    nestedVectorMap.push_back(innerMap2);
    // 遍历打印所有元素
    for (const auto& innerMap : nestedVectorMap) {
        for (const auto& pair : innerMap) {
            std::cout << pair.first << ": " << pair.second << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}

输出结果为:

apple: 1 banana: 2 
orange: 3 grape: 4 
  1. Map嵌套vector:
#include <iostream>
#include <map>
#include <vector>
int main() {
    // 创建一个嵌套vector的容器
    std::map<std::string, std::vector<int>> nestedMapVector;
    // 创建并添加第一个内层vector
    std::vector<int> innerVector1 = {1, 2, 3};
    nestedMapVector["A"] = innerVector1;
    // 创建并添加第二个内层vector
    std::vector<int> innerVector2 = {4, 5, 6};
    nestedMapVector["B"] = innerVector2;
    // 遍历打印所有元素
    for (const auto& pair : nestedMapVector) {
        std::cout << pair.first << ": ";
        for (const auto& num : pair.second) {
            std::cout << num << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}

输出结果为:

A: 1 2 3 
B: 4 5 6 

这些示例展示了如何在STL中创建和使用嵌套容器。嵌套容器的设计可以根据需求灵活变化,允许我们构建复杂的数据结构来满足特定的应用场景。

关注我,不迷路,共学习,同进步

关注我,不迷路,共学习,同进步

相关文章
|
7月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
177 2
|
7月前
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
345 73
|
8月前
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
7月前
|
存储 算法 C++
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
287 3
|
8月前
|
存储 算法 C++
【c++丨STL】priority_queue(优先级队列)的使用与模拟实现
本文介绍了STL中的容器适配器`priority_queue`(优先级队列)。`priority_queue`根据严格的弱排序标准设计,确保其第一个元素始终是最大元素。它底层使用堆结构实现,支持大堆和小堆,默认为大堆。常用操作包括构造函数、`empty`、`size`、`top`、`push`、`pop`和`swap`等。我们还模拟实现了`priority_queue`,通过仿函数控制堆的类型,并调用封装容器的接口实现功能。最后,感谢大家的支持与关注。
391 1
|
9月前
|
C++ 容器
【c++丨STL】stack和queue的使用及模拟实现
本文介绍了STL中的两个重要容器适配器:栈(stack)和队列(queue)。容器适配器是在已有容器基础上添加新特性或功能的结构,如栈基于顺序表或链表限制操作实现。文章详细讲解了stack和queue的主要成员函数(empty、size、top/front/back、push/pop、swap),并提供了使用示例和模拟实现代码。通过这些内容,读者可以更好地理解这两种数据结构的工作原理及其实现方法。最后,作者鼓励读者点赞支持。 总结:本文深入浅出地讲解了STL中stack和queue的使用方法及其模拟实现,帮助读者掌握这两种容器适配器的特性和应用场景。
188 21
|
9月前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
136 16
|
10月前
|
算法 网络安全 区块链
2023/11/10学习记录-C/C++对称分组加密DES
本文介绍了对称分组加密的常见算法(如DES、3DES、AES和国密SM4)及其应用场景,包括文件和视频加密、比特币私钥加密、消息和配置项加密及SSL通信加密。文章还详细展示了如何使用异或实现一个简易的对称加密算法,并通过示例代码演示了DES算法在ECB和CBC模式下的加密和解密过程,以及如何封装DES实现CBC和ECB的PKCS7Padding分块填充。
199 4
2023/11/10学习记录-C/C++对称分组加密DES
|
8月前
|
存储 算法 C++
深入浅出 C++ STL:解锁高效编程的秘密武器
C++ 标准模板库(STL)是现代 C++ 的核心部分之一,为开发者提供了丰富的预定义数据结构和算法,极大地提升了编程效率和代码的可读性。理解和掌握 STL 对于 C++ 开发者来说至关重要。以下是对 STL 的详细介绍,涵盖其基础知识、发展历史、核心组件、重要性和学习方法。
|
10月前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
205 1