题目描述
使用C++自带的stack栈模板来实现四则运算表达式求值
算法描述参考第3.2.5节
算法伪代码参考P53-54的算法3.4
例如
1. Push (OPTR, '#');表示把字符#压入堆栈OPTR中,转换成c++代码就是OPTR.push('#');
2. Pop(OPND, a); 表示弹出栈OPND的栈顶元素,并把栈顶元素放入变量a中。因此改成c++代码是两个操作:a = OPND.top(); OPND.pop();
3. a = GetTop(OPND)表示获取栈OPND的栈顶元素,转成c++代码就是: a = OPND.top();
大家主要是改造表达式求值函数EvaluateExpression的代码
提示
本题需要把一个字符串转成浮点数,例如字符串"1.234"转成浮点数1.234
因为C++11开始取消atof函数,所以C++要用sscanf函数来实现该转换,参考代码如下
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char TempData[]="1.23456";
double dd;
sscanf(TempData, "%lf", &dd);
cout<<dd<<endl;
return 0;
}
输入
第一个输入t,表示有t个实例
第二行起,每行输入一个表达式,每个表达式末尾带#表示结束
输入t行
输出
每行输出一个表达式的计算结果,计算结果用浮点数(含2位小数)的格式表示
参考代码如下:
#include <iostream>
#include<iomanip>
using namespace std;
int main()
{
double temp = 12.345678
cout<<fixed<<setprecision(2)<<temp<<endl;
}
输出结果为12.35
输入输出样例
输入样例1 <-复制
2
1+2*3-4/5#
(66+(((11+22)*2-33)/3+6)*2)-45.6789#
输出样例1
6.20
54.32
AC代码
#include <iostream>
#include <string>
#include <cstring>
#include <stack>
#include <iomanip>
using namespace std;
#define OPSETSIZE 7
unsigned char Prior[7][7] = { //运算符间的优先关系
'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>',
'>','>','>','>','<','>','>',
'>','>','>','>','<','>','>',
'<','<','<','<','<','=',' ',
'>','>','>','>',' ','>','>',
'<','<','<','<','<',' ','='
};
char OPSET[OPSETSIZE] = { '+' , '-' , '*' , '/' ,'(' , ')' , '#' }; //运算符集合
double Operate(double a, unsigned char theta, double b); //计算类似a+b的表达式结果
bool In(char Test, char* TestOp); //判断字符Test是否是运算符,是则返回true
char precede(char Aop, char Bop); //返回两个运算符优先级的比较结果
//以下完成算术表达式求值函数EvaluateExpression(string MyExp)的填空
double EvaluateExpression(string MyExp) //算术表达式求值算法
//设OPTR和OPND分别为运算符栈和运算数栈
//参数MyExp是表达式字符串
{
stack<char> OPTR; //运算符栈,字符元素
stack<double> OPND; //运算数栈,实数元素
char TempData[20];
double Data, a, b, r;
char theta, c, x, Dr[2];
OPTR.push('#');
strcpy(TempData, "\0");
int i = 0; //表达式字符串的当前字符位置
c = MyExp[i]; //表达式字符串的当前字符
//逐个读入表达式字符串的字符到变量c,并识别为数值或运算符,做相应处理
/********** Write your code here! **********/
while (c != '#'||OPTR.top()!='#')
{
if (!In(c, OPSET))
{
int k = 0;
while (!In(c, OPSET))
{
TempData[k] = c;
k++;
i++;
c = MyExp[i];
}
TempData[k] = '\0';
double dd;
sscanf(TempData, "%lf", &dd);
OPND.push(dd);
}
else
{
switch (precede(OPTR.top(), c))
{
case '<':
OPTR.push(c);
i++;
c = MyExp[i];
break;
case '=':
OPTR.pop();
i++;
c = MyExp[i];
break;
case '>':
theta = OPTR.top();
OPTR.pop();
b = OPND.top();
OPND.pop();
a = OPND.top();
OPND.pop();
OPND.push(Operate(a, theta, b));
break;
}
}
}
return OPND.top();
/*******************************************/
} //这是函数EvaluateExpression的右花括号
//函数EvaluateExpression的代码到此结束
//以下填空完成其他函数的定义,包括函数Operate\函数In\函数precede
//可以参考教材光盘中文件夹CHAP03的源代码ALGO0304.cpp,几乎照抄
/********** Write your code here! **********/
double Operate(double a, unsigned char theta, double b)
{
switch (theta)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
}
}
bool In(char Test, char* TestOp)
{
int i = 0;
for (i = 0; i < 7; i++)
{
if (Test == TestOp[i])
return 1;
}
return 0;
}
char precede(char Aop, char Bop)
{
int i=0, j=0;
while (OPSET[i] != Aop)
i++;
while (OPSET[j] != Bop)
j++;
return Prior[i][j];
}
/*******************************************/
//主函数
int main()
{
string Exp;
int t;
double result;
cin >> t;
while (t--)
{
cin >> Exp;
result = EvaluateExpression(Exp);
cout << fixed << setprecision(2) << result << endl;
}
return 0;
}
(by 归忆)