计算一个表达式的运算结果
使用C++自带stack堆栈对象来实现
输入
第一个输入t,表示有t个实例
第二行起,每行输入一个表达式,每个表达式末尾带#表示结束
输入t行
输出
每行输出一个表达式的计算结果,计算结果用浮点数(含4位小数)的格式表示
用cout控制浮点数输出的小数位数,需要增加一个库文件,并使用fixed和setprecision函数,代码如下:
#include <iostream>
#include<iomanip>
using namespace std;
int main()
{ double temp = 12.34
cout<<fixed<<setprecision(4)<<temp<<endl;
}
输出结果为12.3400
样例输入
2
1+2*3-4/5#
(66+(((11+22)*2-33)/3+6)*2)-45.6789#
样例输出
6.2000
54.3211
本题用两个栈(一个表达式栈,一个数字栈)来实现。
#include <iostream>
#include <stack>
#include <iomanip>
using namespace std;
void postfix(char pre[],char post[],int &n); // 把中缀表达式转换为后缀表达式
double read_number(char str[],int &i); // 将数字字符串转变成相应的数字
void postfix_value(char post[]); // 由后缀表达式字符串计算相应的中值表达式
bool isoperator(char op); // 判断是否为运算符
int priority(char op); // 求运算符优先级
int main()
{
int t;
cin>>t;
while(t--){
char exp[1001];
char post[1001];
int n=0;
cin>>exp;
postfix(exp,post,n);
postfix_value(post);
}
return 0;
}
bool isoperator(char op)
{
switch(op){
case '+':
case '-':
case '*':
case '/':
return 1;
default :
return 0;
}
}
int priority(char op)
{
switch(op){
case '#':
return -1;
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default :
return -1;
}
}
//把中缀表达式转换为后缀表达式,返回后缀表达式的长度(包括空格)
void postfix(char pre[],char post[],int &n)
{
int i=0,j=0;
stack<char> s;
s.push('#'); // 首先把结束标志‘#’放入栈底
while(pre[i]!='#'){
if((pre[i]>='0' && pre[i]<='9') || pre[i]=='.'){ // 遇到数字和小数点直接写入后缀表达式
post[j++]=pre[i];
n++;
}
else if(pre[i]=='(') // 遇到“(”不用比较直接入栈
s.push(pre[i]);
else if(pre[i] ==')'){ // 遇到右括号将其对应左括号后的操作符(操作符栈中的)全部写入后缀表达式
while(s.top()!='('){
post[j++]=s.top();
s.pop();
n++;
}
s.pop(); // 将“(”出栈,后缀表达式中不含小括号
}
else if(isoperator(pre[i])){
post[j++]=' '; // 用空格分开操作数(
n++;
while(priority(pre[i])<=priority(s.top())){
// 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程
post[j++]=s.top();
s.pop();
n++;
}
s.push(pre[i]); //当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈
}
i++;
}
while(!s.empty()){ //将所有的操作符加入后缀表达式
post[j++]=s.top();
s.pop();
n++;
}
post[j]='\0';
}
double read_number(char str[],int &i)
{
double x=0.0;
int k=0;
while(str[i]>='0' && str[i]<='9'){ // 处理整数部分
x=x*10+(str[i]-'0');
i++;
}
if(str[i]=='.'){ //处理小数部分
i++;
while(str[i]>='0' && str[i]<='9'){
x=x*10+(str[i]-'0');
(i)++;
k++;
}
}
while(k!=0){
x/=10.0;
k--;
}
return x;
}
void postfix_value(char post[])
{
stack<double> s; // 操作数栈
int i=0 ;
double x1,x2;
while(post[i]!='#'){
if(post[i]>='0' && post[i]<='9')
s.push(read_number(post,i));
else if(post[i]==' ')
i++;
else if (post[i]=='+'){
x2=s.top();
s.pop();
x1=s.top();
s.pop();
s.push(x1+x2);
i++;
}
else if(post[i] =='-'){
x2=s.top();
s.pop();
x1=s.top();
s.pop();
s.push(x1-x2);
i++;
}
else if(post[i] =='*'){
x2=s.top();
s.pop();
x1=s.top();
s.pop();
s.push(x1*x2);
i++;
}
else if(post[i] =='/'){
x2=s.top();
if(x2==0){
cout<<"error"<<endl;
return ;
}
s.pop();
x1=s.top();
s.pop();
s.push(x1/x2);
i++;
}
}
cout<<fixed<<setprecision(4)<<s.top()<<endl;
}