day19--栈

用两个栈实现队列

栈:先进后出;队列:先进先出==>因此两个栈即可模拟队列

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;
    }
};

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值