用两个栈实现队列
栈:先进后出;队列:先进先出==>因此两个栈即可模拟队列
class Solution
{
public:
void push(int node) {//进队
stack1.push(node);//进栈
}
int pop() {//出队
int t;
if(stack2.empty()){//栈2空
while(!stack1.empty()){//栈1不空
t=stack1.top(); //将栈1中的元素出栈放入栈2,直到栈1空
stack2.push(t);
stack1.pop();
}
}
t=stack2.top(); stack2.pop();//2出栈==>先进先出
return t;
}
private:
stack<int> stack1;
stack<int> stack2;
};
包含min函数的栈
class Solution {
public:
stack<int> st, mst;
void push(int value) {
st.push(value);
if(mst.empty() || mst.top()>value) mst.push(value);
else mst.push(mst.top());//保证栈顶为最小的值
}
void pop() {
st.pop();
mst.pop();
}
int top() {
return st.top();
}
int min() {
return mst.top();
}
};
有效括号序列
class Solution {
public:
/**
* @param s string字符串
* @return bool布尔型
*/
stack<char> st;
bool isValid(string s) {
int len=s.size();
for(int i=0;i<len;i++){
//第一次遇到右括号,则不匹配
if(i==0 && (s[i]==')'||s[i]=='}'||s[i]==']')) return false;
//栈空或遇到左括号,进栈
if(st.empty()||s[i]=='('||s[i]=='{'||s[i]=='[') st.push(s[i]);
else{
if(st.top()=='('&&s[i]==')' || st.top()=='{'&&s[i]=='}' || st.top()=='['&&s[i]==']') st.pop();//匹配则出栈
else return false;//不匹配,直接返回
}
}//字符串不空,全部匹配则栈为空
if(st.empty() && len!=0) return true;
else return false;//栈不空,或字符串为空
}
};
表达式求值
将算数表达式变为后缀表达式步骤:
while(string s){
从s中读取字符c;
c为数字: 将后续所有数字依次存放在postexp中,并以字符"#标志数值串结束;
c为左括号"(": 将"("进栈 ;
c为右括号")": 将op栈"("之前的运算符依次出栈并存入postexp中,再将"("出栈;
c为"+"或"-": 将op栈中"("之前的运算符依次并存入postexp中,再将"+"或"-"进栈;
c为"*"或"/": 将op栈中"("之前的"*"或"/"依次并存入postexp中,再将"*"或"/"进栈;
}
字符串s扫描完,则出栈op中所有运算符并存到postexp中
后缀表达式的计算步骤:
while(postexp){
从postexp中读取字符c;
c为"+": 从栈中出栈两个数值a,b,计算c=a+b,将c入栈;
c为"-": 从栈中出栈两个数值a,b,计算c=b-a,将c入栈;
c为"*": 从栈中出栈两个数值a,b,计算c=b*a,将c入栈;
c为"/": 从栈中出栈两个数值a,b,若a!=0, 计算c=b/a,将c入栈;
c为字符:将连续的数字串转化为数值d,将d入栈;
}
#include <stack>
#include <vector>
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 返回表达式的值
* @param s string字符串 待计算的表达式
* @return int整型
*/
int solve(string s) {
vector<char> postexp; // 后缀表达式
stack<char> op; //操作符
//将算数表达式转换为后缀表达式(逆波兰式,计算机方便处理的形式)
for (int i=0; i<s.size(); i++) {
if(s[i]>='0' && s[i] <='9'){
postexp.push_back(s[i]); // 数字进栈
continue;
}else {
if(s[i-1]>='0' && s[i-1]<='9')
postexp.push_back('#');//符号前加"#"标志,确定数字位
}// 符号为(或栈空或栈顶为(,直接栈
if(s[i]=='('||op.empty()||op.top()=='(') op.push(s[i]);
else{
switch (s[i]) {
case ')'://将(之前的运算符出栈放在postexp中
while(op.top()!='('){
postexp.push_back(op.top()); op.pop();
}op.pop();//将(出栈
break;
case '+'://+、- 将(之前的运算符出栈放在postexp,再将+或-进栈
case '-':
while(!op.empty() && op.top()!='('){
postexp.push_back(op.top()); op.pop();
}op.push(s[i]);
break;
case '*'://*、/ 将(之前的*、/出栈放在postexp,再将*或*进栈
if(op.top()=='*'){//只有栈顶为*才出栈
while(!op.empty() && op.top()=='*'){
postexp.push_back(op.top());op.pop();
}op.push(s[i]);
}else op.push(s[i]);
break;
default: break;
}
}
}//将栈内全部存入postexp中
if(postexp.back()>='0'&&postexp.back()<='9') postexp.push_back('#');
while(!op.empty()){
postexp.push_back(op.top()); op.pop();
}
//计算后缀表达式
int res=0;
stack<int> st;
for(int i=0;i<postexp.size();i++){
if(postexp[i]>='0' && postexp[i]<='9'){
int num=0;
while (postexp[i]!='#') {
num = num*10 + postexp[i]-'0';
i++;
}st.push(num);
}else if(postexp[i]=='+' || postexp[i]=='-' || postexp[i]=='*'){
int op2=st.top(); st.pop();//先出栈的是第二个操作数
int op1=st.top(); st.pop();//第一个操作数
switch (postexp[i]) {
case '+': res = op1 + op2; break;
case '-': res = op1 - op2; break;
case '*': res = op1 * op2; break;
}
st.push(res);
}
}
return res;
}
};