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