描述
输入一个中缀算术表达式,求解表达式的值。运算符包括+、-、*、/、(、)、=,参加运算的数为double类型且为正数。(要求:直接针对中缀算术表达式进行计算,不能转换为后缀或前缀表达式再进行计算,只考虑二元运算即可。)
输入
多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾。当表达式只有一个“=”时,输入结束。参加运算的数为double类型。
输出
对于每组数据输出一行,为表达式的运算结果。输出保留两位小数。
输入样例 1
2+2=
20*(4.5-3)=
=
输出样例 1
4.00
30.00
#include <iostream>
#include <stdlib.h>
#include <cstring>
#include<iomanip>//该头文件为了后面的输出保留两位小数
#define MAXSIZE 100//初始分配的存储空间
#define OK 1
#define OVERFLOW -2
#define ERROR -1
using namespace std;
typedef struct {
char* base;
char* top;
int stacksize;
} SqStackOPTR;
//字符栈
typedef struct {
double* base;
double* top;
int stacksize;
} SqStackOPND;
//数据栈
int InitStack(SqStackOPTR& S) {
S.base = new char[MAXSIZE];
if (!S.base) exit(OVERFLOW);
S.top = S.base;
S.stacksize = MAXSIZE;
return OK;
}
int InitStack(SqStackOPND& S) {
S.base = new double[MAXSIZE];
if (!S.base) exit(OVERFLOW);
S.top = S.base;
S.stacksize = MAXSIZE;
return OK;
}
int Push(SqStackOPTR& S, char e) {
if(S.top-S.base==S.stacksize) return ERROR;
*S.top++ = e;
return OK;
}
int Push(SqStackOPND& S, double e) {
if(S.top-S.base==S.stacksize) return ERROR;
*S.top++ = e;
return OK;
}
//字符栈出栈
char Pop(SqStackOPTR& S) {
char e;
if (S.top == S.base) return ERROR;
e = *--S.top;
return e;
}
//数字栈出栈
double Pop(SqStackOPND& S) {
double e;
if (S.top == S.base) return ERROR;
e = *--S.top;
return e;
}
char GetTop(SqStackOPTR S) {
char e;
if (S.top == S.base) return ERROR;
e = *(S.top - 1);
return e;
}
double GetTop(SqStackOPND S) {
double e;
if (S.top == S.base) return ERROR;
e = *(S.top - 1);
return e;
}
int In(char ch) {
int isNumber;
switch (ch) {
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
case '=': isNumber = 1; break;
default: isNumber = 0; break;
}
return isNumber;
}
//定义一个判定运算符栈的栈顶元素与读入的运算符之间优先关系的函数
char Precede(char top, char ch) {
char sym;
switch (top) {
case '+':
case '-':
switch (ch) {
case '+':
case '-':
case ')':
case '=': sym = '>'; break;
case '*':
case '/':
case '(': sym = '<'; break;
} break;
case '*':
case '/':
switch (ch) {
case '+':
case '-':
case '*':
case '/':
case ')':
case '=': sym = '>'; break;
case '(': sym = '<'; break;
}break;
case '(':
switch (ch) {
case '+':
case '-':
case '*':
case '/':
case '(':sym = '<'; break;
case ')': sym = '='; break;
}break;
case ')':
switch (ch) {
case '+':
case '-':
case '*':
case '/':
case ')':
case '=':sym = '>'; break;
}break;
case '=':
switch (ch) {
case '+':
case '-':
case '*':
case '/':
case '(':sym = '<'; break;
case '=': sym = '='; break;
} break;
}
return sym;
}
//char Precede(char top, char ch)另一种写法
//{
// if((top=='('&&ch==')')||(top=='='&&ch=='=') )return '=';
// else
// if(((top=='+'||top=='-'||top=='*'||top=='/'||top==')') && (ch=='+'||ch=='-'||ch==')'||ch=='='))||((top=='*'||top=='/'||top==')')&&(c=h='*'||ch=='/')))return '>';
// else
// if(((top=='('||top=='=')&&ch!=')'&&ch!='=')|| ((top=='+'||top=='-')&&(ch=='*'||ch=='/'))||top=='('||ch=='(') return '<';
// else
// cout<<c1<<" "<<c2<<"没有输出"<<endl;
//
//}
double Operate(double a, char top, double b) {
double sum = 0;
switch (top) {
case '+': sum = a + b; break;
case '-':sum = a - b; break;
case '*': sum = a * b; break;
case '/':sum = a / b; break;
}
return sum;
}
double EvaluateExpression(char ch) {
SqStackOPTR OPTR;
SqStackOPND OPND;
InitStack(OPTR);
InitStack(OPND);
Push(OPTR, '=');
char chs[20];//定义一个字符数组,来实现数字转换为字符串
memset(chs, '#', sizeof(char) * 20);//将字符数组的元素设置为‘#’ 即初始化chs数组 不然会报错
while (ch != '=' || GetTop(OPTR) != '=') {//表达式没有扫描完毕或OPTR的栈顶元素不为“=”
if (!In(ch)) {
//这里应该将字符串转换为数字
for (int i = 0; i < strlen(chs); i++) {
if (chs[i] == '#' && !In(ch)) {//如果数组的第i个元素不为‘#’或不为符号
chs[i] = ch;
cin >> ch;
}
else {
break;
}
}
double d = atof(chs);//把字符串转换成浮点数 double
Push(OPND, d);
memset(chs, '#', sizeof(char) * 20);//将字符数组的元素设置为‘#’
}
else {
switch (Precede(GetTop(OPTR), ch)) {
case '<':
Push(OPTR, ch); cin >> ch;
break;
case '>':
char theta;
double b;
double a;
theta = Pop(OPTR);
b = Pop(OPND);
a = Pop(OPND);
double sum;
sum = Operate(a, theta, b);
Push(OPND, sum);
break;
case '=':
Pop(OPTR);
cin >> ch;
break;
}
}
}
return GetTop(OPND);
}
int main() {
while (1) {
char ch;
cin >> ch;
if (ch == '=')break;
double res = EvaluateExpression(ch);
cout << fixed << setprecision(2) << res << endl;//输出保留两位小数
}
return 0;
}