蓝桥杯必学 4 大 STL 容器详解(stack/queue/unordered_map/unordered_set)
本文最后更新于 34 天前,其中的信息可能已经有所发展或是发生改变。

通用前提

所有容器使用前需包含对应头文件,核心规则:

  • 判空优先:访问容器元素(如栈顶、队头)前,必须用empty()判断是否为空,避免程序崩溃;
  • 效率优先:优先用unordered_*(哈希实现,O (1) 效率),仅需排序时换map/set(红黑树,O (logn));
  • 核心接口:每个容器只需记 5 个左右核心用法,无需死记所有接口。

第一部分:stack(栈)—— 先进后出(FILO)

一、核心定位

蓝桥杯高频必考,专门处理 “后进先出” 场景,比如 DFS 搜索、括号匹配、表达式求值,是算法题的 “回溯工具”。

二、基础知识点

1. 定义方式(需包含头文件#include <stack>

cpp

运行

// 定义存储int类型的栈,可替换为string/char/结构体等
stack<int> st;
// 示例:存储字符串的栈
stack<string> st_str;

2. 核心接口(仅需记这 5 个,按使用频率排序)

接口功能注意点
st.push(x)入栈:把元素 x 添加到栈顶无返回值,仅添加
st.pop()出栈:删除栈顶元素无返回值!仅删除,不返回元素
st.top()取栈顶元素:返回栈顶的值必须先判空(!st.empty()),否则崩溃
st.empty()判断栈是否为空返回 bool(空 = true,非空 = false),访问 top 前必用
st.size()获取栈内元素个数返回整数,偶尔用于统计

3. 核心特性

  • 只能访问栈顶元素,无法访问中间 / 栈底元素(“封死” 的容器,仅能操作顶部);
  • 所有操作都是对栈顶的 “增 / 删 / 查”,符合 “先进后出”(比如先压 1、2、3,取的时候先取 3)。

三、实战案例(蓝桥杯高频:括号匹配)

题目场景

判断输入的字符串中的括号是否合法(仅包含()/[]/{}),合法条件:

  1. 左括号必须用相同类型的右括号闭合;
  2. 左括号必须按正确顺序闭合(如([)]不合法)。

完整代码(可直接运行)

cpp

运行

#include <iostream>
#include <stack>
#include <string>
using namespace std;

// 判断括号是否匹配
bool isMatch(char left, char right) {
    if ((left == '(' && right == ')') || 
        (left == '[' && right == ']') || 
        (left == '{' && right == '}')) {
        return true;
    }
    return false;
}

int main() {
    string s;
    cout << "请输入括号字符串:";
    cin >> s;
    
    stack<char> st; // 存储左括号的栈
    bool isValid = true; // 标记是否合法
    
    for (char c : s) { // 遍历每个字符
        // 左括号:入栈
        if (c == '(' || c == '[' || c == '{') {
            st.push(c);
        } 
        // 右括号:匹配栈顶左括号
        else {
            // 无左括号匹配 → 非法
            if (st.empty()) {
                isValid = false;
                break;
            }
            // 取出栈顶左括号,判断是否匹配
            char top_char = st.top();
            st.pop(); // 匹配成功则出栈
            if (!isMatch(top_char, c)) {
                isValid = false;
                break;
            }
        }
    }
    
    // 最后栈必须为空(所有左括号都匹配完成)
    if (isValid && st.empty()) {
        cout << "括号合法!" << endl;
    } else {
        cout << "括号非法!" << endl;
    }
    
    return 0;
}

运行结果示例

plaintext

// 示例1:合法
请输入括号字符串:()[]{}
括号合法!

// 示例2:非法(顺序错误)
请输入括号字符串:([)]
括号非法!

// 示例3:非法(左括号多余)
请输入括号字符串:((()))]
括号非法!

竞赛技巧

  • 栈是处理 “嵌套 / 回溯” 问题的核心,比如表达式求值、DFS 手动实现(递归栈溢出时用栈替代);
  • 记住 “左括号入栈,右括号匹配出栈” 的核心逻辑,可解决所有括号类问题。

第二部分:queue(队列)—— 先进先出(FIFO)

一、核心定位

蓝桥杯顶级高频,BFS(广度优先搜索)的 “标配工具”,解决迷宫、最短路径、层序遍历等问题,是搜索题的 “通关钥匙”。

二、基础知识点

1. 定义方式(需包含头文件#include <queue>

cpp

运行

// 定义存储int类型的队列
queue<int> q;
// 示例:存储结构体(比如迷宫的坐标)
struct Pos { int x, y; };
queue<Pos> q_pos;

2. 核心接口(仅需记这 6 个)

接口功能注意点
q.push(x)入队:把元素 x 添加到队列尾部无返回值
q.pop()出队:删除队列头部元素无返回值!仅删除
q.front()取队头元素:返回队列第一个元素必须先判空(!q.empty()
q.back()取队尾元素:返回队列最后一个元素偶尔用,非核心
q.empty()判断队列是否为空访问 front 前必用
q.size()获取队列元素个数层序遍历(BFS)时统计层数可用

3. 核心特性

  • 只能访问队头 / 队尾,无法访问中间元素;
  • 符合 “先进先出”(比如先入 1、2、3,取的时候先取 1),适合 “顺序处理” 场景。

三、实战案例(蓝桥杯经典:BFS 走迷宫)

题目场景

迷宫为 5×5 的二维数组,0表示可走,1表示墙,从起点(0,0)走到终点(4,4),求最短步数(BFS 是求最短路径的最优解)。

完整代码(可直接运行)

cpp

运行

#include <iostream>
#include <queue>
using namespace std;

// 迷宫大小
const int N = 5;
// 迷宫地图(0=可走,1=墙)
int maze[N][N] = {
    {0, 1, 0, 0, 0},
    {0, 1, 0, 1, 0},
    {0, 0, 0, 1, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 0, 0}
};
// 方向:上下左右(BFS核心,遍历四个方向)
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
// 记录是否访问过(避免重复走)
bool visited[N][N] = {false};

// 存储坐标和步数的结构体
struct Node {
    int x, y; // 坐标
    int step; // 到该位置的步数
};

int main() {
    queue<Node> q; // BFS的核心队列
    // 起点入队:(0,0),步数0
    q.push({0, 0, 0});
    visited[0][0] = true; // 标记已访问
    
    int min_step = -1; // 最短步数,默认-1(无解)
    
    // BFS核心循环:队列不为空则继续
    while (!q.empty()) {
        // 取出队头元素(当前位置)
        Node cur = q.front();
        q.pop(); // 出队
        
        // 到达终点:记录步数并退出
        if (cur.x == N-1 && cur.y == N-1) {
            min_step = cur.step;
            break;
        }
        
        // 遍历四个方向
        for (int i = 0; i < 4; i++) {
            int nx = cur.x + dx[i];
            int ny = cur.y + dy[i];
            // 条件1:坐标在迷宫范围内
            // 条件2:不是墙
            // 条件3:未被访问过
            if (nx >= 0 && nx < N && ny >=0 && ny < N 
                && maze[nx][ny] == 0 && !visited[nx][ny]) {
                // 新位置入队,步数+1
                q.push({nx, ny, cur.step + 1});
                visited[nx][ny] = true; // 标记已访问
            }
        }
    }
    
    if (min_step != -1) {
        cout << "走到终点的最短步数:" << min_step << endl;
    } else {
        cout << "无法到达终点!" << endl;
    }
    
    return 0;
}

运行结果

plaintext

走到终点的最短步数:8

竞赛技巧

  • BFS 的核心逻辑:“队头出队→处理当前节点→邻接节点入队”,必须用 queue 实现;
  • 记住 “方向数组 + 访问标记 + 队列存坐标 / 步数” 的组合,可解决所有迷宫 / 最短路径问题;
  • queue 的front()pop()必须成对使用(取完队头就出队,避免重复处理)。

第三部分:unordered_map(哈希映射)—— 键值对存储

一、核心定位

蓝桥杯高频,解决 “统计频率、哈希映射、快速查找” 问题,比如统计字符 / 数字出现次数、记录键值关联关系。

二、基础知识点

1. 定义方式(需包含头文件#include <unordered_map>

cpp

运行

// 定义:unordered_map<键类型, 值类型> 变量名
unordered_map<string, int> mp; // 字符串为键,整数为值(统计字符频率)
unordered_map<int, bool> mp_vis; // 整数为键,布尔值为值(标记是否访问)

2. 核心接口(仅需记这 6 个)

接口功能注意点
mp[key] = value赋值:给键 key 绑定值 value核心!最常用,key 不存在则自动创建,值默认初始化(int=0,bool=false)
mp.find(key)查找:找键 key 是否存在返回迭代器,存在则指向该键值对,不存在则返回mp.end()
mp.erase(key)删除:删除键 key 对应的键值对无返回值,key 不存在则无操作
mp.empty()判断是否为空返回 bool
mp.size()获取键值对个数统计不同键的数量
mp.count(key)统计 key 出现次数仅返回 0/1(因为 key 唯一),等价于find判存在

3. 核心特性

  • 键(key)唯一:同一个键只能存一个值,重复赋值会覆盖;
  • 哈希实现:查找 / 赋值效率 O (1),比map快,竞赛优先用;
  • 无序存储:键的顺序不固定,若需排序则换map

三、实战案例(蓝桥杯高频:统计字符频率)

题目场景

输入一个字符串,统计每个字符出现的次数,并按字符输出(比如输入abac,输出a:2, b:1, c:1)。

完整代码(可直接运行)

cpp

运行

#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

int main() {
    string s;
    cout << "请输入字符串:";
    cin >> s;
    
    unordered_map<char, int> mp; // 键=字符,值=出现次数
    
    // 统计频率:遍历每个字符
    for (char c : s) {
        mp[c]++; // 核心!key不存在则默认0,++后变为1;存在则累加
    }
    
    // 遍历输出结果(遍历unordered_map)
    cout << "字符频率统计:" << endl;
    for (auto& pair : mp) { // pair.first=键(字符),pair.second=值(次数)
        cout << pair.first << ": " << pair.second << endl;
    }
    
    // 单独查询某个字符的频率
    char target;
    cout << "请输入要查询的字符:";
    cin >> target;
    if (mp.find(target) != mp.end()) { // 判断字符是否存在
        cout << target << " 出现次数:" << mp[target] << endl;
    } else {
        cout << target << " 未出现!" << endl;
    }
    
    return 0;
}

运行结果示例

plaintext

请输入字符串:bluecup123123
字符频率统计:
3: 2
2: 2
1: 2
p: 1
u: 1
c: 1
e: 1
u: 1
l: 1
b: 1
请输入要查询的字符:1
1 出现次数:2

竞赛技巧

  • mp[key]++是统计频率的 “万能写法”,无需判断 key 是否存在;
  • 判存在优先用mp.find(key) != mp.end(),比mp.count(key)更直观;
  • 需排序时(比如按字符顺序输出),把unordered_map换成map即可(用法完全一致)。

第四部分:unordered_set(哈希集合)—— 去重 + 快速判存

一、核心定位

蓝桥杯高频,解决 “自动去重、快速判断元素是否存在” 问题,比如数组去重、判断元素是否访问过。

二、基础知识点

1. 定义方式(需包含头文件#include <unordered_set>

cpp

运行

// 定义:unordered_set<元素类型> 变量名
unordered_set<int> st; // 存储整数的集合
unordered_set<string> st_str; // 存储字符串的集合

2. 核心接口(仅需记这 5 个)

接口功能注意点
st.insert(x)插入:添加元素 x 到集合自动去重,重复插入无效果
st.find(x)查找:判断元素 x 是否存在返回迭代器,存在则指向 x,不存在则返回st.end()
st.erase(x)删除:删除元素 x无返回值,x 不存在则无操作
st.empty()判断是否为空返回 bool
st.size()获取集合元素个数统计不同元素的数量

3. 核心特性

  • 元素唯一:自动去重,插入重复元素不会报错,但集合中仅存一个;
  • 哈希实现:查找 / 插入效率 O (1),竞赛优先用;
  • 无序存储:元素顺序不固定,需排序则换set

三、实战案例(蓝桥杯高频:数组去重)

题目场景

输入一个整数数组(长度不限),去除重复元素,输出去重后的数组和不同元素的个数。

完整代码(可直接运行)

cpp

运行

#include <iostream>
#include <unordered_set>
#include <vector>
using namespace std;

int main() {
    vector<int> nums = {1, 2, 2, 3, 3, 3, 4, 5, 5}; // 测试数组
    unordered_set<int> st; // 用于去重的集合
    
    // 数组去重:插入集合(自动去重)
    for (int num : nums) {
        st.insert(num);
    }
    
    // 输出去重后的元素
    cout << "去重后的数组:";
    for (int num : st) {
        cout << num << " ";
    }
    cout << endl;
    
    // 输出不同元素个数
    cout << "不同元素的个数:" << st.size() << endl;
    
    // 快速判断元素是否存在
    int target = 3;
    if (st.find(target) != st.end()) {
        cout << target << " 存在于数组中!" << endl;
    } else {
        cout << target << " 不存在!" << endl;
    }
    
    return 0;
}

运行结果

plaintext

去重后的数组:1 2 3 4 5 
不同元素的个数:5
3 存在于数组中!

竞赛技巧

  • 去重的 “懒人写法”:把数组 / 字符串元素全部插入unordered_set,自动完成去重;
  • 判存在的核心:if (st.find(x) != st.end()),比遍历数组快(O (1) vs O (n));
  • 需排序时换set,用法完全一致,仅输出顺序不同。

核心总结(必背)

容器核心特性蓝桥杯核心场景最常用接口
stack先进后出括号匹配、DFS、表达式求值push/pop/top/empty
queue先进先出BFS、迷宫 / 最短路径、排队模拟push/pop/front/empty
unordered_map键值对、哈希、键唯一统计频率、哈希映射、判存在mp[key]=value/find/erase
unordered_set元素唯一、哈希、去重数组去重、快速判存在insert/find/erase

学习优先级

  1. 先掌握queue(BFS 是蓝桥杯搜索题核心);
  2. 再掌握stack(括号匹配 / DFS);
  3. 最后掌握unordered_map+unordered_set(统计 / 去重);
  4. 每个容器练 1-2 道对应场景的题,即可完全掌握,无需死记接口。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇