1476: 括号括号————(STL,栈的模拟)

本文介绍了一个使用栈数据结构实现的括号匹配算法,用于判断给定括号序列是否正确配对。通过遍历输入字符串并将括号压入或弹出栈来实现匹配检查。

1476: 括号括号
时间限制: 3 Sec 内存限制: 128 MB

提交: 339 解决: 66 统计
题目描述
小明今年上大学,在大学里发现有很多同学都女朋友,两人整天都在一起腻歪,小明看到后感觉很孤单,现在,给你一行括号序列,你来判断一下其中的括号是否配对。
输入
多组输入,每一组第一行输入一个数 T ( 0 &lt; &lt; N ≤ ≤ 100 ) T(0&lt;&lt;N≤≤100) T0<<N100,表示有T组测试数据。后面的T行输入多组输入数据,每组输入数据都是一个字符串S(S的长度小于10000,且S不是空串),测试数据组数少于5组。数据保证S中只含有"[", “]”, “(”, “)” 四种字符

输出
每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No。
样例输入
3
[(])
(])
([])
样例输出
No
No
Yes
来源
刘帅坤


这道题在输入输出的时候有个坑点,就是输入n的时候也需要

while(~scanf("%d",&n))
{
	while(n--)
	{
		//这里写内容
	}
}

然后就用一个栈来模拟就行了,不能匹配的括号直接推到栈里,感觉这道题和消消乐有点儿像,能够匹配的,就可以直接消除,不能够匹配的还存在里边,

这道题并不是统计左括号和有括号的数目然后匹配的

只有左括号在左边,有括号在右边,如果左右括号中间有东西的话,中间的括号也是能够匹配才行
匹配: [ (   ) ] [(\ )] [( )] [   ] [   ] [   ] [   ] \quad [\ ][\ ][\ ][\ ] [ ][ ][ ][ ], [   [   ]   (   )   ] \quad [\ [\ ]\ (\ )\ ] [ [ ] ( ) ], (   [   [   ] (   )   ]   ) \quad (\ [\ [\ ](\ )\ ]\ ) ( [ [ ]( ) ] )
不匹配: ] [   ] [   ] [   , [   (   ]   ) ][\ ][\ ][\ ,\quad [\ (\ ]\ ) ][ ][ ][ ,[ ( ] )
规则就是这样子,然后找
我就是把这个字符串直接遍历一遍,一个一个的判断是否可以推到栈里
先把s[0]推到栈里
对于字符串里的每一个字符
如果能够推到栈里,那么这个字符就是栈顶
在判断在字符串里的下一个字符看看是否与栈顶元素匹配
如果匹配,那么就把栈顶元素取出,在判断字符串里的下一个字符

如果括号全部匹配,那么栈的大小为0,输出Yes,否则输出No


code:

#include<bits/stdc++.h> 
using namespace std;
const int MAXN=1e4+9;
int main()
{
	char s[MAXN];
	int n;
	while(~scanf("%d",&n))
	{
		while(n--)
		{
			scanf("%s",s);
			int len=strlen(s);
			stack<char> sta;
			sta.push(s[0]);
			for(int i=1;i<len;i++)
			{
				if(sta.size()&&s[i]==']'&&sta.top()=='[')
				{
					sta.pop();
					continue;
				}
				if(sta.size()&&s[i]==')'&&sta.top()=='(')
				{
					sta.pop();
					continue;
				}
				sta.push(s[i]);
			 } 
			if(sta.size())	printf("No\n");
			else			printf("Yes\n");
		}
	 } 
	return 0;
}

1. std::vector —— 动态数组 ✅ 特点: 底层为连续内存的动态数组; 支持随机访问(O(1) 下标访问); 可以动态扩容(自动双倍增长); 是最常用、最灵活的容器。 ⏱ 时间复杂度: 操作 复杂度 访问元素 vec[i] O(1) 尾部插入/删除 push_back/pop_back 均摊 O(1) 中间插入/删除 O(n) 查找元素 O(n) 📌 使用场景: 替代普通数组,避免手动管理大小; 存图(邻接表)、存储输入数据、DP 数组等; 实现或队列(配合 push_back 和 pop_back); 💡 示例代码: 🔧 技巧: 使用 vec.reserve(n) 预分配空间,避免频繁扩容; vector<bool> 是特化版本,行为异常,慎用。 2. std::queue 和 std::priority_queue —— 队列与优先队列 ✅ std::queue 先进先出(FIFO)结构。 常用于 BFS、模拟任务调度等。 主要操作: 示例(BFS): ✅ std::priority_queue 默认是最大堆,顶部始终是最大元素; 常用于 Dijkstra、Huffman 编码、贪心算法等。 默认行为(大根堆): C++ std::priority_queue<int> pq; pq.push(3); pq.push(1); pq.push(4); std::cout << pq.top(); // 输出 4 小根堆写法: C++ std::priority_queue<int, std::vector<int>, std::greater<int>> min_pq; 自定义比较(结构体): ⚠️ 注意:priority_queue 不支持修改已有元素,也不能遍历。 3. std::stack —— 后进先出(LIFO),适合 DFS、括号匹配、表达式求值等。 常用操作: C++ s.push(x); s.pop(); // 无返回值 s.top(); // 返回顶 示例: 4. std::deque —— 双端队列 双向队列,可在头尾高效插入/删除; 支持随机访问; push_front, pop_front, push_back, pop_back 均为 O(1); vector 扩容时会失效迭代器,而 deque 更稳定。 使用场景: 单调队列(滑动窗口最大值); BFS 中需要从前或后插入的情况; 实现双端队列类问题。 示例: 5. std::set / std::multiset —— 有序集合 ✅ std::set 内部基于红黑树实现,自动排序且去重; 插入、删除、查找均为 O(log n); 不支持下标访问,但可用迭代器遍历。 常用操作: 使用场景: 动态维护一个有序唯一集合; 查询前驱/后继(lower_bound / upper_bound); 替代平衡树。 ✅ std::multiset 允许重复元素的 set; 同样有序,支持 insert, erase, find, lower_bound 等; 删除单个元素时使用 erase(s.find(x)) 防止全部删除; erase(x) 会删掉所有等于 x 的元素! 6. std::map / std::unordered_map —— 关联容器(键值对) ✅ std::map 键值对容器,按键有序排列(红黑树); 插入、查找、删除:O(log n); 键自动排序,可遍历得到有序结果。 示例: ✅ std::unordered_map 基于哈希表实现; 平均操作复杂度 O(1),最坏 O(n); 不保证顺序; 在竞赛中常用于快速映射(如字符串 → ID、计数等)。 示例: C++ std::unordered_map<std::string, int> cnt; cnt["apple"]++; cnt["banana"]++; ⚠️ 注意事项: 哈希碰撞可能导致被卡(尤其在线评测系统),可加随机扰动防 hack; 对自定义类型需提供 hash 函数,否则不支持。 7. std::array —— 固定大小数组(C++11 起) 类似内置数组,但更安全、支持 STL 操作; 大小在编译期确定; 性能极高,适用于固定长度的小数组。 示例: C++ std::array<int, 5> arr = {1, 2, 3, 4, 5}; for (int x : arr) std::cout << x << " "; 8. std::pair 和 std::tuple —— 组合类型 ✅ std::pair<T1, T2> 存储两个元素的组合; 常用于 map 键值、priority_queue 中带权值的节点; 支持字典序比较(<),便于排序。 示例: C++ std::pair<int, std::string> p = {3, "hello"}; std::vector<std::pair<int, int>> edges; edges.push_back({u, v}); ✅ std::tuple 多元组,可存多个不同类型元素; 使用 std::make_tuple, std::tie, std::get 操作。 C++ auto t = std::make_tuple(1, "abc", 3.14); int a; std::string b; double c; std::tie(a, b, c) = t; 9. 其他实用技巧与组合使用 场景 推荐容器组合 图的邻接表表示 vector<vector<int>> 或 vector<vector<pair<int, int>>>(带权) 并查集 vector<int> 存 parent 数组 字符串哈希映射 unordered_map<string, int> 滑动窗口最大值 deque<int> 实现单调队列 Top-K 问题 priority_queue<int>(小根堆维护 K 个最大) 动态排名查询 set<int> + distance(s.begin(), it)(但慢,可用 PBDS 替代) ❗常见陷阱提醒 错误 正确做法 map[key] 会创建默认值,可能改变结构 查找用 find() 避免插入 vector 迭代器在 push_back 后可能失效 使用索引或重新获取 erase(remove(...)) 忘记写法 vec.erase(std::remove(vec.begin(), vec.end(), x), vec.end()); priority_queue 无法遍历 若需遍历,改用 vector + make_heap 或排序 unordered_map 被哈希攻击 加随机种子或切换到 map 给出以上内容的对应代码,并且简要注释功能
最新发布
10-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值