1358:中缀表达式值(expr)时间限制: 1000 ms 内存限制: 65536 KB 提交数: 4486 通过数: 1536 【题目描述】输入一个中缀表达式(由0-9组成的运算数、加+减-乘*除/四种运算符、左右小括号组成。注意“-”也可作为负数的标志,表达式以“@”作为结束符),判断表达式是否合法,如果不合法,请输出“NO”;否则请把表达式转换成后缀形式,再求出后缀表达式的值并输出。 注意:必须用栈操作,不能直接输出表达式的值。 【输入】一行为一个以@结束的字符串。 【输出】如果表达式不合法,请输出“NO”,要求大写。 如果表达式合法,请输出计算结果。 【输入样例】1+2*8-9@ 【输出样例】8 |
教学备忘录:编辑 |
无 |
给学生提示:编辑 |
无 |
一本通题目1365(题解链接)加上一个判断表达式是否合法 判断情况详见注释
#include <iostream>
#include <cstdio>
#include <stack>
#include <cmath>
#include <string>
using namespace std;
stack <int> digit; // 数字栈
stack <char> symbol; // 字符栈
string str; // 保存输入的字符串
int len;
int level(char ch) { // 判断字符优先级
if (ch == '+' || ch == '-') return 1;
if (ch == '*' || ch == '/') return 2;
return 0;
}
void calculation() { // 加减乘除运算
int a = digit.top();
digit.pop();
int b = digit.top();
digit.pop();
char ch = symbol.top();
symbol.pop();
if (ch == '+') digit.push(a + b); // 运算后将结果如数字栈
if (ch == '-') digit.push(b - a);
if (ch == '*') digit.push(a * b);
if (ch == '/') digit.push(b / a);
}
void solve() {
int x = 0;
bool tag = false;
for (int i = 0; i < len; i ++) {
if (str[i] >= '0' && str[i] <= '9') { // 计算连续的数字
x = x*10 + str[i]-'0';
tag = true;
}
else { // 当前字符不为数字时
if (tag) { // 如果上一个字符是数字就入栈
digit.push(x);
x = 0;
tag = false;
}
if (str[i] == '(') {
symbol.push(str[i]);
continue;
}
if (str[i] == ')') {
while (symbol.top() != '(') {
calculation();
}
symbol.pop();
continue;
}
while (!symbol.empty() && level(symbol.top()) >= level(str[i])) {
calculation();
}
symbol.push(str[i]);
}
}
if (tag) { // 最后的数字也要入栈
digit.push(x);
}
while (!symbol.empty()) {
calculation();
}
cout << digit.top() << endl;
}
bool check() { // 检查表达式是否合法
if (len == 1) return level(str[0]) > 0 ? false : true; // 单独一个运算符的情况
for (int i = 1; i < len; i ++) { // 连续两个运算符的情况
if (level(str[i]) && level(str[i-1])) return false;
}
int sum = 0;
for (int i = 0; i < len; i ++) { // 判断括号是否匹配
if (str[i] == '(') sum ++;
else if (str[i] == ')') sum --;
}
return sum == 0;
}
int main()
{
cin >> str;
len = str.length() - 1;
if (str[0] == '-') digit.push(0);
if (!check()) { // 表达式不合法
cout << "NO" << endl;
}
else { // 表达式计算
solve();
}
return 0;
}