表达式求值3

Description

小明在你的帮助下破解了Ferrari密码,正要往前走,突然又出现一个密码门,门上有一个算式,

其中只有“(”、 “)”、“0~9”、“+”、“-”、“*”、“/”、“^”

求出的值就是密码。小明数学学得不好,还需要你帮他的忙。(“/”用div。)

Format

Input

输入 共1行,为一个算式

Output

输出 共1行,就是密码。

Samples

输入数据 1

(((1+2)^3*4)-5/6)/6

Copy

输出数据 1

18

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <unordered_map>
using namespace std;
stack<int> num;
stack<char> op;
int m;
char ch[200];
char str[200];
void eval() {
    // 由于栈先进后出的性质,a为倒数第二个数,b为倒数第一个数,因为顺序回影响减法和除法
    int b = num.top();
    num.pop();
    int a = num.top();
    num.pop();
    int c = op.top();
    op.pop();
    int x;
    if(c == '+') x = a + b;
    else if(c == '-') x = a - b;
    else if(c == '*') x = a * b;
    else if(c == '/') x = a / b;
    else if(c == '^'){
        x=1;
        for(int i=1;i<=b;i++){
            x*=a;
        }
    }
    num.push(x);
}
int main() 
{
    unordered_map<char, int> pr {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}, {'^', 3}}; // 优先级
    cin >> ch + 1;
    int len = strlen (ch + 1);
    ch[0] = '(';
    ch[len + 1] = ')';
    //给输入原字符串最外层加上一对左右括号 
    m=0;
    for (int i = 0; i <= len+1; i ++) 
    //对于充当正负号的"+","-",在它的前面加个数字0 
    {
        if (ch[i - 1] == '(' && (ch[i] == '-' || ch[i] == '+'))
            str[++ m] = '0';
        str[++ m] = ch[i];
    }
    for(int i = 1; i <=m; i ++) 
    {
        char c = str[i];
        if(isdigit(c)) //如果输入的是一个数字字符,将其转成一个数字 
        {
            int j = i, x = 0;
            while(j <m&& isdigit(str[j]))
                x = x * 10 + str[j ++] - '0';
            i = j - 1; // 更新i的位置
            num.push(x);
        } 
        else 
            if(c == '(') //如果是左括号,直接进栈 
              op.push(c);
            else 
                if(c == ')') //如果是右括号,其比所有运算符的级别都要低,于是不断进行运算
                //直到遇到一个左括号 
                {
                      while(op.top() != '(')
                             eval();
                      op.pop(); // 把'('pop掉
                } 
                else 
                //既不是数字字符,也不是左右括号,其必然为运算符 
                    {
                          while(op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) 
                          //只要放在运算符栈顶的运算符级别高于当前读入的字符
                          //则可取出运算符栈顶的运算符与数字所在栈顶的两个数字进行相关运算 
                               eval();
                          op.push(c);  //将当前字符加入运算符栈 
                    }
    }
    cout << num.top() << endl;
    return 0;
}

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值