表达式计算
给出一个表达式,其中运算符仅包含+,-,*,/,^(加 减 乘 整除 乘方)要求求出表达式的最终值。
数据可能会出现括号情况,还有可能出现多余括号情况。
数据保证不会出现大于或等于231的答案。
数据可能会出现负数情况。
输入格式
输入仅一行,即为表达式。
输出格式
输出仅一行,既为表达式算出的结果。
输入样例:
(2+2)^(1+1)
输出样例:
16
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stack>
using namespace std;
// ops 操作符栈 stk 数字栈
stack<char> ops;
stack<int> stk;
// 快速幂,求 a^b
int qmi(int a, int b) {
int s = 1;
while (b --) s *= a;
return s;
}
// 表达式计算
void calc() {
// a 是后一个数,b 才是前一个数
int a = stk.top(); stk.pop();
int b = stk.top(); stk.pop();
char c = ops.top(); ops.pop();
int d;
if (c == '+') d = a + b;
else if (c == '-') d = b - a;
else if (c == '*') d = a * b;
else if (c == '/') d = b / a;
else d = qmi(b, a);
stk.push(d);
}
int main() {
string s, left;
cin >> s;
// 因为可能会出现多个括号的情况,若 ( 则无所谓,但 ) 会 对结果造成影响,所以加尽可能多的左括号
for (int i = 0; i <= s.size(); i ++) left += '(';
s = left + s + ')';
for (int i = 0; i < s.size(); i ++) {
// 先判断是数字的情况
if (s[i] >= '0' && s[i] <= '9') {
int j = i, t = 0;
while (s[j] >= '0' && s[j] <= '9') {
t = t * 10 + s[j] - '0';
j ++;
}
i = j - 1;
stk.push(t);
} else {
char c = s[i];
// 判断是 +、- 的情况
if (c == '+' || c == '-') {
// 若当前字符是 -,判断前一个字符是不是数字或右括号,
// 若不是数字且不是 ) ,则是负数,否则为运算符,若是则按负数处理,否则按运算符处理
if (c == '-' && i && !(s[i - 1] >= '0' && s[i - 1] <= '9' || s[i - 1] == ')')) {
// 若是 -() 这种情况,则将之处理为 -1 * ()
// 大坑
if (s[i + 1] == '(') {
stk.push(-1);
ops.push('*');
} else {
// i 是 -, 所以从 i + 1 开始
int j = i + 1, t = 0;
while (s[j] >= '0' && s[j] <= '9') {
t = t * 10 + s[j] - '0';
j ++;
}
i = j - 1;
stk.push(-t);
}
// 若是操作符号,则弹出 ops 栈顶,并弹出两个数字进行运算
} else {
while (ops.top() != '(') calc();
// 计算完后把当前运算符入栈
ops.push(c);
}
// 若是 *、/ 则栈顶元素只有优先级更高时才进行运算
} else if (c == '*' || c == '/') {
while (ops.top() == '*' || ops.top() == '/' || ops.top() == '^') calc();
// 计算完后把当前运算符入栈
ops.push(c);
// 若是 ^ 则只有栈顶元素是 ^ 才会进行运算
} else if (c == '^') {
while (ops.top() == '^') calc();
// 计算完后把当前运算符入栈
ops.push(c);
// 若是 ) 因为从后往前优先级降低,所以直接弹出运算,知道遇到 ( 停止
} else if (c == ')') {
while (ops.top() != '(') calc();
// 把 ( 踢出栈
ops.pop();
// 若是 ( 则直接入栈即可
} else if (c == '(') {
ops.push(c);
} else {
// 方便调错
puts("Invailde Operation!");
}
}
}
cout << stk.top() << endl;
return 0;
}