当前位置: 首页 > article >正文

STL 库基础概念与示例

一、STL 库基础概念与示例

1. 容器分类
顺序容器
  • 核心特性:按元素插入顺序存储,支持下标访问(类似数组),动态扩展内存。
  • 典型容器vector(动态数组)。
  • 适用场景:需要频繁按顺序访问、尾部插入 / 删除的场景(如队列、栈模拟)。
关联容器
  • 核心特性:按元素值的大小自动排序(默认升序),存储位置由值决定,键唯一(set/map的键不可重复)。
  • 典型容器
    • set:键值合一(存储的值即键),用于唯一值存储和快速查找。
    • map:键值对存储(key-value),键唯一,值可重复。
  • 底层结构:二叉搜索树(set/map默认使用红黑树,插入时自动平衡排序)。
2. 常用容器操作对比
操作vector(顺序容器)set(关联容器)map(关联容器)
构造vector<int> v;set<int> s;map<string, int> m;
新增元素v.push_back(10);(尾部插入)s.insert(10);(自动去重、排序)m.insert({"apple", 5}); 或 m["apple"] = 5;
删除元素v.erase(it);(需迭代器定位)s.erase(10);(直接传值删除)m.erase("apple");(按键删除)
修改元素v[0] = 20;(下标直接修改)不可直接修改键(需 s.erase(old_val); s.insert(new_val);m["apple"] = 10;(直接修改值)
查询元素需自定义 find 函数(线性查找)s.find(10) != s.end();(返回迭代器)m.find("apple") != m.end();(按键查找)
遍历方式下标遍历、迭代器、范围 for迭代器、范围 for(不支持下标)迭代器、范围 for
排序需调用 sort(v.begin(), v.end());自动排序(插入时二叉树调整)自动按键排序
3. 关键注意点
  1. vector 不支持 << 运算符输出
    • 需手动遍历元素,不能直接 cout << v;
  2. set 的键不可修改
    • 若需修改键值,必须先删除旧元素,再插入新元素。
  3. map 的键唯一,值可重复
    • 键用于排序和查找,值可灵活修改(如统计频率)。

二、示例代码

示例 1:vector 存储整数(顺序容器)

cpp

#include <iostream>
#include <vector>
#include <algorithm> // 用于sort
using namespace std;int main() {vector<int> nums;// 插入元素nums.push_back(3);nums.push_back(1);nums.push_back(2);// 遍历(下标方式)cout << "插入顺序:";for (int i = 0; i < nums.size(); i++) {cout << nums[i] << " "; // 输出:3 1 2}// 排序(需手动调用sort)sort(nums.begin(), nums.end());cout << "\n排序后:";for (auto num : nums) { // 范围for遍历cout << num << " "; // 输出:1 2 3}return 0;
}

关键点vector 按插入顺序存储,需手动排序,支持下标和迭代器遍历。

示例 2:set 统计唯一字符(关联容器)和 去重

cpp

#include <iostream>
#include <set>
using namespace std;int main() {string str = "hello";set<char> unique_chars;// 插入字符(自动去重,'l' 只存一次)for (char c : str) {unique_chars.insert(c);}// 遍历(自动排序:'e', 'h', 'l', 'o')cout << "唯一字符:";for (char c : unique_chars) {cout << c << " "; // 输出:e h l o}return 0;
}
#include <iostream>         // 包含输入输出流头文件,用于cin/cout
#include <set>              // 包含set容器头文件,用于有序存储和自动去重
#include <string>           // 包含字符串头文件,用于处理输入的字符序列
using namespace std;        // 使用标准命名空间,简化代码书写// 定义Data类,用于存储字符及其出现次数
class Data {
private:char ch;                // 私有成员:存储字符(作为set的键,决定排序和唯一性)int count;              // 私有成员:存储字符出现的次数
public:// 构造函数:初始化字符和计数,默认计数为1(首次出现)Data(char ch, int count = 1) : ch(ch), count(count) {}// 重载<运算符:用于set容器排序(按字符的ASCII值升序)bool operator<(const Data& r) const { return ch < r.ch;    // 比较字符大小,确保set有序存储}// 重载后增量运算符++(int):处理字符重复出现的计数增加void operator++(int) const { // 由于函数为const,需通过强制类型转换修改非const成员(注意:此写法不推荐,可能破坏const正确性)((Data*)this)->count++; }// 显示函数:输出字符及其出现次数void show() const { cout << ch << "出现了:" << count << "次" << endl; }
};int main() {while (1) {              // 无限循环,持续处理用户输入set<Data> s;         // 创建set容器,存储Data对象(自动去重、按ch排序)string str;          // 用于存储用户输入的字符串cout << "请输入字符:";cin >> str;          // 读取用户输入的一行字符// 遍历输入字符串的每个字符for (int i = 0; str[i]; i++) { // 插入字符到set中,insert返回pair<iterator, bool>:// first为插入位置迭代器,second表示是否插入成功(true=新插入,false=已存在)auto p = s.insert(Data(str[i])); // 如果插入失败(字符已存在),则找到已存在的元素并增加计数if (!p.second) { (*p.first)++; // 通过迭代器访问已存在的Data对象,调用后增量运算符}}// 遍历set,输出每个字符的出现次数(set自动按ch排序)for (auto ele : s) { ele.show();       // 调用show方法输出结果}}return 0;
}

关键点set 自动去重并按字符 ASCII 值排序,插入重复元素无效。

示例 3:map 统计单词频率(关联容器)

cpp

#include <iostream>
#include <map>
#include <string>
using namespace std;int main() {string sentence = "apple banana apple orange";map<string, int> word_freq; // key=单词,value=频率// 统计频率(用operator[]修改值)for (string word : {"apple", "banana", "apple", "orange"}) {word_freq[word]++; // 键不存在时自动创建,值初始化为0后+1}// 遍历输出(按键自动排序:apple, banana, orange)cout << "单词频率:" << endl;for (const auto& pair : word_freq) {cout << pair.first << ": " << pair.second << endl;// 输出:// apple: 2// banana: 1// orange: 1}return 0;
}

关键点map 按键自动排序,operator[] 简化值的修改,键唯一(重复插入同一键会更新值)。

三、总结

  • 顺序容器(如vector)适合 “按顺序操作” 场景,需手动处理排序和查找。
  • 关联容器(如set/map)适合 “快速查找、去重、排序” 场景,底层二叉树结构保证高效操作(O(log n))。
  • 开发中根据需求选择容器:需顺序访问选vector,需唯一键选set,需键值对选map
http://www.lryc.cn/news/2401266.html

相关文章:

  • Spring MVC参数绑定终极手册:单多参/对象/集合/JSON/文件上传精讲
  • Fluence推出“Pointless计划”:五种方式参与RWA算力资产新时代
  • innovus: ecoAddRepeater改变hier层级解决办法
  • 华为OD机试真题——硬件产品销售方案(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
  • 突破数据孤岛:StarRocks联邦查询实战指南
  • 传统业务对接AI-AI编程框架-Rasa的业务应用实战(1)--项目背景即学习初衷
  • 低功耗架构突破:STM32H750 与 SD NAND (存储芯片)如何延长手环续航至 14 天
  • CSS选择子元素
  • git cherry-pick (28)
  • android与Qt类比
  • AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片 支持高清CMOS Sensor输入 国产品牌
  • Linux(11)——基础IO(上)
  • ABP-Book Store Application中文讲解 - Part 9: Authors: User Interface
  • 鸿蒙开发修改版本几个步骤
  • Hive自定义函数案例(UDF、UDAF、UDTF)
  • 【学习笔记】Circuit Tracing: Revealing Computational Graphs in Language Models
  • 3D视觉重构工业智造:解码迁移科技如何用“硬核之眼“重塑生产节拍
  • Elasticsearch中的刷新(Refresh)和刷新间隔介绍
  • STM32标准库-TIM定时器
  • 【算法训练营Day05】哈希表part1
  • CMap应用场景和例子
  • Kafka 如何保证顺序消费
  • 【算法题】算法一本通
  • Modbus转Ethernet IP赋能挤出吹塑机智能监控
  • C++中如何遍历map?
  • 什么是终端安全管理系统(终端安全管理软件2024科普)
  • 书籍转圈打印矩阵(8)0604
  • 【JVM】Java类加载机制
  • Elasticsearch中的自定义分析器(Custom Analyzer)介绍
  • 《C++初阶之入门基础》【C++的前世今生】