栈练习题

发布时间 2023-12-27 18:23:04作者: Lost-in-love

单调栈(洛谷P5788)


题目大意

中的向右看齐相同


题解

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int N=3e6+5;
int a[N],ans[N],n;
stack<int>s;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=n;i>=1;i--){
        while(!s.empty()&&a[s.top()]<=a[i])s.pop();
        if(s.empty())ans[i]=0;
        else ans[i]=s.top();
        s.push(i);
    }
    for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
    return 0;
}

后缀表达式(洛谷P1449)


题目大意

计算后缀表达式的值


解题思路

利用栈计算后缀表达式

未知的代码
#include<bits/stdc++.h>
using namespace std;
string s;
stack<string>st;
int main(){
	getline(cin,s);
	int p=0;
	while(s[p]!='@'){
		string tmp;
		while(s[p]!='.'&&isdigit(s[p]))tmp+=s[p++];
		if(s[p]!='.'){
			int a=stoi(st.top());st.pop();
			int b=stoi(st.top());st.pop();
			switch(s[p]){
				case '+':st.push(to_string(b+a));break;
				case '-':st.push(to_string(b-a));break;
				case '*':st.push(to_string(b*a));break;
				case '/':st.push(to_string(b/a));break;
			}
		}
		else st.push(tmp);
		p++;
	}
	cout<<st.top();
	return 0;
}

表达式求值(P1981)


题目大意

对一个字符串算数表达式计算求值。表达式只有加法和乘法,不含括号。


解题思路

先将所有乘法计算出来,转化为只有加法,最后相加求解。

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int mod=1e4;
stack<int>s;
int main(){
	int a,b;
	char op;
	cin>>a;
	s.push(a%mod);
	while(cin>>op>>b){
		if(op=='+')s.push(b);
		else{
			a=s.top();
			s.pop();
			s.push(a*b%mod);
		}
	}
	a=0;
	while(!s.empty()){
		a+=s.top();
		s.pop();
	}
	cout<<a%mod<<endl;
	return 0;
}

表达式括号匹配(P1175)


题目大意

给定中缀表达式,输出转化后缀表达式后的每一次运算操作后的后缀表达式。


解题思路

先将中缀表达式转为后缀表达式,需要考虑运算符优先级,然后按优先级顺序和先后顺序依次计算并输出。对于给定的中缀表达式字符串s,遍历每个字符,根据字符的类型进行相应的操作:如果是数字,则直接添加到结果字符串;如果是'(',则将其压入栈中;如果是')',则将栈顶元素弹出并添加到结果字符串,直到遇到'(',然后将'('从栈中弹出;如果是运算符,则比较其与栈顶运算符的优先级,如果栈顶运算符优先级高于等于当前运算符,则将栈顶元素弹出并添加到结果字符串,直到栈为空或栈顶运算符优先级低于当前运算符,然后将当前运算符压入栈中。最后,将栈中剩余的运算符依次弹出并添加到结果字符串。

未知的代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	cin>>s;
	auto priority=[&](char c){
		switch(c){
			case '+':
			case '-':return 1;
			case '*':
			case '/':return 2;
			case '^':return 3;
			case '(':
			case ')':return 0;
			default:return -1;
		}
	};
	auto to_suffix=[&](string&s){
		string ans;
		stack<char>st;
		for(auto&it:s){
			if(isdigit(it))ans+=it;
			else if(it=='(')st.push(it);
			else if(it==')'){
				while(!st.empty()&&st.top()!='('){
					ans+=st.top();
					st.pop();
				}
				if(!st.empty())st.pop();
			}else{
				while(!st.empty()&&priority(st.top())>=priority(it)){
					if(priority(st.top())==priority(it)&&it=='^')break;
					ans+=st.top();
					st.pop();
				}
				st.push(it);
			}
		}
		while(!st.empty()){
			ans+=st.top();
			st.pop();
		}
		return ans;
	};
	auto calc_part=[&](int a,int b,char op){
		switch(op){
			case '+': return a+b;
			case '-': return a-b;
			case '*': return a*b;
			case '/': return a/b;
			case '^': return (int)pow(a,b);
			default: return -1;
		}
	};
	auto calc=[&](string s){
		vector<int>l;
		for(auto&it:s)cout<<it<<' ';
		cout<<endl;
		for(auto it=s.begin();it!=s.end();it++){
			if(isdigit(*it))l.push_back(*it-'0');
			else{
				int a=l.back();
				l.pop_back();
				int b=l.back();
				l.pop_back();
				l.push_back(calc_part(b,a,*it));
				for(auto&v:l)cout<<v<<' ';
				for(auto jt=it+1;jt!=s.end();jt++)cout<<*jt<<" ";
				cout<<endl;
			}
		}
	};
	calc(to_suffix(s));
	return 0;
}