栈的性质(进栈,出栈,访问)

C++ stack 栈

头文件:#include<stack>

栈:后进先出 LIFO,后压入栈的元素,最先拿出来。

常用成员汇总

函数 作用
st.push(x) 将x压入栈顶
st.top() 获取栈顶元素,不删除
st.pop() 删除栈顶,void无返回
st.empty() 栈空返回true
st.size() 返回栈中元素数量

注意:栈不能遍历,不能随机访问sti,只能操作栈顶。

2.可以存什么类型

cpp 复制代码
stack<int> st1;
stack<pair<int,int>> st2;
stack<string> st3;

//pair入栈
st2.push({1,2});
auto p = st2.top();
st2.pop();

3.栈使用场景

  1. ** 括号匹配**(经典)
    . P1739 表达式括号匹配 - 洛谷

​**32. 最长有效括号 - 力扣(LeetCode)**

一键直达​ P1739 32

​ 2.模拟进出栈

吐泡泡

Rails

​一键直达 吐泡泡 Rails

4.栈的例题

P1739 表达式括号匹配 - 洛谷

复制代码
#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<char> st;
    char c;
    while (cin >> c) {
        if (c == '#') break; 
        if (c == '(') {
            st.push(c);
        } else if (c == ')') {
            if (st.empty()) {
                cout << "NO" << endl;
                return 0;
            }
            st.pop();
        }
    }
    if (st.empty()) {
        cout << "YES" << endl;
    } else {
        cout << "NO" << endl;
    }
    return 0;
}

题目:判断括号是否匹配。

思路:

遇到左括号 '(' 入栈;

遇到右括号 ')'

  • 如果栈为空,直接不匹配;
  • 否则弹出栈顶(抵消一对括号)。
    遍历结束,栈必须为空才算全部匹配。
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main(){
    string s;
    cin>>s;
    stack<char> st;
    bool ok=true;
    for(auto ch:s){
        if(ch=='('){
            st.push(ch);
        }else if(ch==')'){
            if(st.empty()){
                ok=false;
                break;
            }
            st.pop();
        }
    }
    if(ok && st.empty()) cout<<"YES";
    else cout<<"NO";
    return 0;
}

32. 最长有效括号 - 力扣(LeetCode)

题目大意:可以匹配的括号中,所有括号共有多少

思路:遇到左括号,把他的下标进栈,遇到右括号,弹出栈顶,()))像这种尽管前面有2个有效括号,但有个右括号后就不匹配了,更改新的有效长度起点,一直出现右括号,就会进入栈空条件,让当前下标进入栈里,也就更新了有效括号的起始位置,栈里首先要要进一个数字-1,)()或())像这种防止栈里没有左括号时栈空(((()像这种一直出现左括号,栈顶会是出现有效括号最后一次左括号的位置

复制代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
	string s;
	cin>>s;
	stack<int>st;
	st.push(-1);
	int max1=0; 
	for(int i=0;i<s.size();i++)
	{
		if(s[i]=='(')
		st.push(i);
		else
		{
			st.pop();
			//不再有效 ,招到新的栈顶元素 
			if(st.empty())
			st.push(i);
			//在每段有效中找到最长的那段 
			else
			max1=max(max1,i-st.top());
		}
	}
	cout<<max1<<endl;
}

吐泡泡

题目大意:oo==O,OO=空,按照这个规则把字符串压缩

思路:栈空时直接把此元素入栈,并且退出循环,遍历下一个字符,遇到oo时,变为O后要循环有没有和O能消的,遇到OO时,消完后退出此次循环,读取下一个字符,不是这两种情况的,记录当前字符退出循环,读取下一个字符

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define pii pair<int,int>
#define fi first
#define se second
const int N=101;

void slove(){
    string s;
    cin>>s;
    stack<char>st; 
    for(auto c:s){
        char now = c;
        // 必须while循环,如果为空的话,只会把当前字符入栈,
		//不能产生两种字符对比,要退出循环 
        while(true)
        {
            if(st.empty()){
                st.push(now);
                break;
            }
            char tp = st.top();
            //这里还要进行循环,这里结合成的O可能会和前面O抵消
			//或者栈空把·O入栈
			//或者o,把O入栈 
            if(tp == 'o' && now == 'o')
            {
                st.pop();
                now = 'O';
            }
            //每次进入一个字符时,都会进行oo,OO这样的结合
			//再不能进行这两种的结合后,就是进入下面两个条件之一
			//退出循环,读入下一个字符 
            else if(tp == 'O' && now == 'O')
            {
                st.pop();
                break;//进行到这,之前能结合的都结合过了,退出去就行 
            }
            //
            else
            {
                st.push(now);//没有可结合的 
                break;
            }
        }
    }
    string s1;
    while(!st.empty()){
        s1.push_back(st.top());
        st.pop();
    }
    reverse(s1.begin(),s1.end());
    cout<<s1<<endl;
}
signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int _;
    cin>>_;
    while(_--)
        slove();
    return 0;
}

Rails

题目大意:模拟这列数字能不能按照给出的出栈方式出栈

思路:当进栈的那个元素与给出的序列前端的那个元素相等时,弹出栈顶,让下一个字符与栈顶元素比较

复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define pii pair<int,int>
#define fi first
#define se second
//把一组从1-n的数字按照入栈和出栈的性质,看能否操作出出栈后是给出的这段序列,
//5 4 1 2 3,5个数字全部入栈了,5 4 弹出后,还没弹出 3 2就先弹出1了
//3 2 1 4 5 
//3 2 4 1 5
//5 4 3 2 1 
void slove(){
    int n;
    while(cin >> n && n != 0) // 读到n=0整体结束
    {
        int target;
        while(cin >> target)
        {
            if(target == 0) break; // 当前n的所有查询结束
            vector<int> seq;
            seq.push_back(target);
            // 读取本行剩余数字
            for(int i=2;i<=n;i++)
            {
                cin >> target;
                seq.push_back(target);
            }
            stack<int> st;
            int now = 1; // 下一个要进站的车厢
            bool ok = true;
            for(int x : seq)
            {
                // 不断入栈直到栈顶等于x
                //再入栈的元素不是栈顶或栈空时,这些元素都进栈 
                while(now <= n && (st.empty() || st.top() != x))
                {
                    st.push(now++);
                }
                //这个数字也要出栈的一样,去掉栈顶,等到下一次循环
				//要出栈的元素X可能就是新的栈顶,如果不出栈,就会进入while进栈 
                if(st.top() == x)
                {
                    st.pop();
                }
                else
                {
                    ok = false;
                    break;
                }
            }
            if(ok) cout << "Yes" << endl;
            else cout << "No" << endl;
        }
        cout << endl; // 每组n处理完输出空行,题目要求
    }
}

signed main(){
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    slove();
    return 0;
}
相关推荐
m0_547486661 小时前
《数据结构与算法》全套PPT课件2026(中国海洋大学)
数据结构·算法
旖旎夜光1 小时前
LeetCode 904:水果成篮(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
乐观勇敢坚强的老彭3 小时前
C++ 竞赛常用算法模板速查表
开发语言·c++·算法
我变成萤火虫3 小时前
河南萌新联赛2026第(三)场:郑州轻工业大学
数据结构·c++·算法·贪心算法·stl·深度优先·哈希算法
白狐_7983 小时前
408数据结构第7章:B树①——基础概念与结构
数据结构·b树
buhuizhiyuci4 小时前
【Linux 篇】数字世界的水流蓄水池 —— IO 缓冲区机制深度实战解析
linux·运维·服务器·c++
liulilittle4 小时前
LLM 推理引擎与内核系统工程原理
c++·ai·llm·内存·memory·core·kernel
Suxing94 小时前
C语言基础分享:从“租房”到“拆迁”,C语言动态内存管理
java·数据结构·算法
啦啦啦啦啦zzzz4 小时前
moduo网络库 Acceptor TcpConnection
服务器·网络·c++·reactor·网络库