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

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.xdnf.cn/news/870067.html

相关文章:

  • 洛谷每日1题-------Day39__P1697 [USACO18JAN] Lifeguards B
  • Vue 生命周期全解析:从创建到销毁的完整旅程
  • Redisson - 实现延迟队列
  • 通过ca证书的方式设置允许远程访问Docker服务
  • 吴恩达机器学习讲义概述
  • 在虚拟宇宙中低语——进程间通信,Linux命名管道的前世今生
  • 哈希表入门:用 C 语言实现简单哈希表(开放寻址法解决冲突)
  • 9.RV1126-OPENCV 视频的膨胀和腐蚀
  • 基于windows系统的netcore架构与SqlServer数据库,实现双机热备。
  • 基于javaweb的SpringBoot公司日常考勤系统设计与实现(源码+文档+部署讲解)
  • 新手小白深入 BCI:实践与进阶(下)
  • 函数调用(Function Calling)
  • 子网划分例题
  • 【Git 合并冲突解决记录:从 “refusing to merge unrelated histories“ 到批量冲突处理】
  • 《高等数学》(同济大学·第7版)第一章第七节无穷小的比较
  • leetcode题解236:二叉树的最近公共祖先
  • 多层感知器MLP实现非线性分类(原理)
  • UDP包大小与丢包率的关系:原理分析与优化实践
  • 语法--06-- 简单句五大形式、系动词
  • Qwen2.5-VL - Vision Transformer(ViT)的patch 处理
  • 固定资产管理系统 ——仙盟创梦IDE
  • 华为云Flexus+DeepSeek征文|实战体验云服务器单机部署和CCE高可用的架构AI赋能
  • Android studio初体验
  • Android Studio 打包时遇到了签名报错问题:Invalid keystore format
  • Excel高级函数使用FILTER、UNIQUE、INDEX
  • 【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录
  • DeepSeek 赋能金融衍生品:定价与风险管理的智能革命
  • 3.3 HarmonyOS NEXT原子化服务开发:卡片设计、轻量部署与场景化编排实战
  • k8s集群安装坑点汇总
  • 02-Redis常见命令