Leetcode 22 10 09

给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外),计算其结果。

表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格  。 整数除法仅保留整数部分。

示例 1:

输入: "3+2*2"
输出: 7
示例 2:

输入: " 3/2 "
输出: 1
示例 3:

输入: " 3+5 / 2 "
输出: 5
说明:

你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。

解题思路:

拿到题直接想起学过的借助栈中缀转后缀,然后再扫描计算,具体思路如下:

此题主要通过如下两个步骤来完成:
1.将输入的中缀表达式转为后缀表达式(即逆波兰表达式)
2.计算逆波兰表达式
用到数据结构主要是栈(stack).

中缀表达式转后缀表达式(逆波兰表达式)

(1)变量及函数说明

getPriority(char ch): 返回运算符的优先级
vector<char> ans: 存储逆波兰表达式
stack<char> op: 暂存未输出的运算符
(2)步骤
i. 如果s[i]为数字,则一直向后寻找到第一个非数字字符,并将之前的数字字符放入ans
ii. 如果s[i]为运算符,则分为以下三种情况:
A. 如果op为空,则直接将运算符s[i]压入栈op;
B. 如果栈op非空,且运算符s[i]的优先级高于栈顶元素的优先级,则直接将元素符s[i]压入栈op;
C. 如果栈op非空,且运算符s[i]的优先级低于或等于栈顶元素的优先级,则弹出栈顶元素,并将其放入ans,直到运算符s[i]的优先级高于栈顶元素的优先级,此时将运算符s[i]压入栈op.

计算后缀表达式(逆波兰表达式)

(1)变量说明:

stack<int> value: 存储操作数以及中间运算结果
(2)步骤:
1. 如果遇到数字,则将其压入栈value;
2. 如果遇到运算符,则从栈value从弹出两个操作数,计算结果,并将结果压入栈value
3. 遍历完逆波兰表达式后,返回value栈顶元素

class Solution {
public:
    // get the priority of the operator
    int getPriority(char ch)
    {
        switch(ch)
        {
            case '+': return 1;
            case '-': return 1;
            case '*': return 2;
            case '/': return 2;
            default: return 0;
        }
    }
    
    vector<char> toRPN(string s)
    {
        vector<char> ans;   
        stack<char> op;    
        int len = s.length();
        for(int i = 0; i < len; ++i)
        {
            if(s[i] == ' ') continue;
            if(s[i] >= '0' && s[i] <= '9')
            {
                while(s[i] >= '0' && s[i] <= '9')
                {
                    ans.push_back(s[i]);
                    ++i;
                }
                ans.push_back(' ');
                --i;
            }
            if(s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/')
            {
                if(op.empty()) op.push(s[i]);
                else
                {
                    if(getPriority(s[i]) > getPriority(op.top()))
                        op.push(s[i]);
                    else
                    {
                        while(!op.empty() && (getPriority(s[i]) <= getPriority(op.top())))
                        {
                            ans.push_back(op.top());
                            ans.push_back(' ');
                            op.pop();
                        }
                        op.push(s[i]);
                    }
                }
                
            }
        }
        while(!op.empty())
        {
            ans.push_back(op.top());
            ans.push_back(' ');
            op.pop();
        }
        return ans;
    }

    int calculateRPN(vector<char> str)
    {
        int len = str.size();
        int value1, value2, ans;
        stack<int> value;
        for(int i = 0; i < len; ++i)
        {
            if(str[i] >= '0' && str[i] <= '9')
            {
                int tmp = str[i] - 48;
                int j = ++i;
                while(str[j] >= '0' && str[j] <= '9')
                {
                    tmp = tmp * 10 + (str[j] - 48);
                    ++j;
                }
                value.push(tmp);
                i = --j;
            }
            if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
            {
                value2 = value.top();
                value.pop();
                value1 = value.top();
                value.pop();
                if(str[i] == '+') ans = value1 + value2;
                else if(str[i] == '-') ans = value1 - value2;
                else if(str[i] == '*') ans = value1 * value2;
                else ans = value1 / value2;
                value.push(ans);
            }
        }
        return value.top();
    }

    int calculate(string s) {
        return calculateRPN(toRPN(s));
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值