描述
输入一个中缀算术表达式,求解表达式的值。运算符包括+、-、*、/、(、)、=,参加运算的数为double类型且为正数。(要求:直接针对中缀算术表达式进行计算,不能转换为后缀或前缀表达式再进行计算,只考虑二元运算即可。)
输入
多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾。当表达式只有一个“=”时,输入结束。参加运算的数为double类型。
输出
对于每组数据输出一行,为表达式的运算结果。输出保留两位小数。
#include<iostream>
#include <stack>
#include <string.h>
#include <stdlib.h> //atof库函数
using namespace std;
//判断优先级
int pre(char c){
if (c == '=')
return 0;
else if (c == '+' || c == '-')
return 1;
else if (c == '*' || c == '/ ')
return 2;
else
return 0;
}
//计算
void Calculate(stack <double> &num, stack <char> &op) {
double b = num.top(); //右操作数
num.pop();
double a= num.top(); //左操作数
num.pop();
char x = op.top(); //操作符
if (x == '+')
num.push(a + b);
else if (x == '-')
num.push(a - b);
else if (x == '*')
num.push(a*b);
else if (x == '/ ')
num.push(a / b);
op.pop(); //弹出操作符
}
int main() {
stack <double> num;
stack <char> op;
char s[1000]; //待输入的字符串
while (scanf("%s",s)!=EOF) {
if (!strcmp(s, "=") ) break; //退出循环的条件
for (int i = 0; s[i] != '\0'; i++){ //字符串结束的标志: != '\0' ***
//①若遍历到的是数字
if (s[i]>='0' && s[i]<='9') {
double temp = atof(s + i); //转化为double【s是数组始址 i是数字字符起始下标】
num.push(temp);
while ((s[i] >= '0' && s[i] <= '9') || s[i] == '.')
{
i++; //寻找数字的组成部分
}
i--; //回到遍历的数字de末尾
}
//②若遍历到的是字符
else
{
if (s[i] == '(') //【左括号】直接入栈
op.push(s[i]);
else if(s[i]==')')//遇到【右括号】从op栈往外弹,直到弹出一个左括号
{
while (op.top()!='(')
{
Calculate(num, op); //计算式子
}
op.pop();//左括号出栈
}
else if (op.empty()||pre(s[i]) > pre(op.top())) { //来了一个【高优先级的运算符】
op.push(s[i]);
}
else if (!op.empty() && pre(s[i]) <= pre(op.top())) { //来了一个【低优先级的运算符】
while (!op.empty()&&pre(op.top())>=pre(s[i]))
{
Calculate(num, op);
}
op.push(s[i]);//当比它优先级高的都出队操作后,将新操作符入队
}
}
}
printf("%.2lf\n", num.top());//结果
num.pop();
op.pop();
}
}