波兰逆波兰表达式

逆波兰表达式

正常表达式转化逆波兰表达式

  • 创建两个栈命名为s1, s2。
  • 遍历待转化的表达式,如果是数字,直接丢进s2。
  • 如果是左括号’(’,丢进s1。
  • 如果是符号’+’, ‘-’, ‘*’, ‘/’,本质上是维护一个运算优先级严格单调递增栈,即如果s1栈顶符号运算优先级高于或者等于当前符号,出栈直到栈空或者栈顶运算符号优先级低于当前符号。如果s1栈顶符号运算优先级低于(不包括等于)当前符号,当前符号入s1。
  • 左括号是优先级最低的。
  • 如果是右括号,把栈内的符号全部弹出放入s2,直到遇到左括号,并丢弃该左括号。
  • 遍历完毕时,s1如果还有东西,全部丢给s2。
  • 此时s2从栈低到栈顶就是一个逆波兰表达式。

逆波兰表达式求值

  • 创建一个栈
  • 遍历逆波兰表达式
  • 遇见数字,丢入栈
  • 遇见符号,出栈num1,删除栈顶,出栈num2,删除栈顶,注意顺序,求值num = num2 ±*/ num1,再一次提示,注意顺序。
  • 然后将num放入栈
  • 最后栈顶元素即为答案。

772. 基本计算器 III

实现一个基本的计算器来计算简单的表达式字符串。

表达式字符串只包含非负整数,算符 +、-、*、/ ,左括号 ( 和右括号 ) 。整数除法需要 向下截断 。

你可以假定给定的表达式总是有效的。所有的中间结果的范围为 [-231, 231 - 1] 。

代码

class Solution {
public:
    int calculate(string s) {
        //表达式转换逆波兰表达式
        //创建双栈
        stack<char> s1;
        stack<string> s2;
        int n = s.size();
        int l = 0;
        while(l < n) {
        	//碰见数字,全部转换丢入s2
            if(s[l] >= '0' && s[l] <= '9') {
                int r = l + 1;
                while(r < n && s[r] >= '0' && s[r] <= '9') {
                    r++;
                }
                s2.push(s.substr(l, r - l));
                l = r;
            }
            //碰见符号
            else {
            	//左括号直接丢入s1
                if(s[l] == '(') {
                    s1.push(s[l]);
                }
                //+-号是运算级最低的,严格单调递增
                else if(s[l] == '+' || s[l] == '-') {
                	//所以即使碰见同一运算级的+-也还是要出栈
                    while(!s1.empty() && (s1.top() == '*' || s1.top() == '/' || s1.top() == '+' || s1.top() == '-')) {
                    	//出栈的符号直接丢入s2
                        string tmp = "";
                        tmp += s1.top();
                        s2.push(tmp);
                        s1.pop();
                    }
                    //最后将当前符号丢入s1
                    s1.push(s[l]);
                }
                //*/是运算级最高的
                else if(s[l] == '*' || s[l] == '/') {
                	//所以仅在碰见同一优先级*/才出栈
                    while(!s1.empty() && (s1.top() == '*' || s1.top() == '/')) {
                        string tmp = "";
                        tmp += s1.top();
                        s2.push(tmp);
                        s1.pop();
                    }
                
                    s1.push(s[l]);
                }
                //碰见右括号
                else if(s[l] == ')'){
                	//s1的符号全部出栈,直到碰见左括号
                    while(!s1.empty() && s1.top() != '(') {
                        string tmp = "";
                        tmp += s1.top();
                        s2.push(tmp);
                        s1.pop();
                    }
                    //丢弃该左括号
                    if(!s1.empty() && s1.top() == '(') {
                        s1.pop();
                    }
                }
                l++;
            }
        }

		//遍历完了如果s1还有符号,全部丢入s2
        while(!s1.empty()) {
            string tmp = "";
            tmp += s1.top();
            s2.push(tmp);
            s1.pop();
        }
        
        //此时s2从栈低到栈顶就是逆波兰表达式
        //转换为vec准备求值
        
        vector<string> vec;
        while(!s2.empty()) {
            vec.emplace_back(s2.top());
            s2.pop();
        }
        
        //逆波兰表达式求值
        //创建一个栈
        stack<int> stk;
        //遍历逆波兰表达式
        
        //由于从栈逐一弹出,所以逆序遍历vec才是逆波兰表达式
        for(int i = vec.size() - 1; i >= 0; i--) {
        	//碰见数字,丢入栈
            if(vec[i].size() != 1 || (vec[i][0] >= '0' && vec[i][0] <= '9')) {
                stk.push(stoi(vec[i]));
            }
            //碰见符号,出两个栈的数,注意顺序,后出栈的数是第一操作数,计算完毕再入栈
            else {
                if(vec[i] == "+") {
                    int num1 = stk.top();
                    stk.pop();
                    int num2 = stk.top();
                    stk.pop();
                    stk.push(num1 + num2);
                }
                else if(vec[i] == "-") {
                    int num1 = stk.top();
                    stk.pop();
                    int num2 = stk.top();
                    stk.pop();
                    stk.push(num2 - num1);                    
                }
                else if(vec[i] == "*") {
                    int num1 = stk.top();
                    stk.pop();
                    int num2 = stk.top();
                    stk.pop();
                    stk.push(num2 * num1);                      
                }
                else {
                    int num1 = stk.top();
                    stk.pop();
                    int num2 = stk.top();
                    stk.pop();
                    stk.push(num2 / num1);  
                }
            }
        }
        return stk.top();
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值