nyoj(表达式求值)
描述
ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入
第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出
每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入
2
1.000+2/4=
((1+2)*5+1)/4=
样例输出
1.50
4.00
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int map[7][7]= //算符间的优先关系,100表示不会出现的情况
{
{1,1,-1,-1,-1,1,1},
{1,1,-1,-1,-1,1,1},
{1,1,1,1,-1,1,1},
{1,1,1,1,-1,1,1},
{-1,-1,-1,-1,-1,0,100},
{1,1,1,1,100,1,1},
{-1,-1,-1,-1,-1,100,0}
};
int cam(char c)
{
switch(c)
{
case '+':
return 0;
case '-':
return 1;
case '*':
return 2;
case '/':
return 3;
case '(':
return 4;
case ')':
return 5;
case '#':
return 6;
}
}
double sol(double x,char c,double y)
{
switch(c)
{
case '+':
return x+y;
case '-':
return x-y;
case '*':
return x*y;
case '/':
return x/y;
}
}
int z(char c)
{
if('0'<=c&&c<='9'||c=='.')
return 1;
if(c==' ')
return -1;
return 0;
}
char str[1005];
char optr[1005];
double opnd[1005];
int main()
{
int t1,t2,k,len;
char ch,zz;
int temp1,temp2;
double a,b;
int t;
scanf("%d",&t);
getchar();
while(t--)
{
gets(str);
len=strlen(str);
str[len-1]='#'; //处理的等于号
t1=t2=k=0;
optr[t1++]='#';
ch=str[k++];
while(ch!='#'||optr[t1-1]!='#')
{
if(z(ch)==1) //操作数入栈
{
opnd[t2++]=atof(&str[k-1]); //把字符串转换成浮点数
while(z(str[k])==1)
k++;
ch=str[k++];
}
else if(z(ch)==-1)
ch=str[k++];
else
{
temp1=cam(optr[t1-1]);
temp2=cam(ch);
if(map[temp1][temp2]==-1) //栈顶元素优先权低
{
optr[t1++]=ch;
ch=str[k++];
}
else if(map[temp1][temp2]==0) //脱括号并接受下一个字符
{
t1--;
ch=str[k++];
}
else //退栈并将运算结果
{
zz=optr[--t1];
a=opnd[--t2];
b=opnd[--t2];
opnd[t2++]=sol(b,zz,a);
}
}
}
printf("%.2lf\n",opnd[0]);
}
return 0;
}
//#include<stdio.h>
//#include<stdlib.h>
//
////数据栈
//typedef struct DA
//{
// float data[1000];
// int pop;
//} SDA;
//
////运算符栈
//typedef struct OP
//{
// char op[1000];
// int pop;
//} SOP;
//
////初始化数据栈
//int InitSDA(SDA * p)
//{
// p->pop = 0;
// return 0;
//}
//
////初始化运算符栈
//int InitSOP(SOP * p)
//{
// p->pop = 0;
// (p->op[p->pop]) = '=';
// (p->pop)++;
// return 0;
//}
//
////数据入栈
//int PushSDA(SDA * p, float d)
//{
// if(p->pop < 1000)
// {
// p->data[p->pop] = d;
// (p->pop)++;
// return 0;
// }
// else
// return 1; //栈满
//}
//
////运算符入栈
//int PushSOP(SOP * p, char c)
//{
// if(p->pop < 1000)
// {
// p->op[p->pop] = c;
// (p->pop)++;
// return 0;
// }
// else
// return 1; //栈满
//}
//
////数据出栈
//int PopSDA(SDA * p, float * d)
//{
// (p->pop)--;
// if(p->pop >= 0)
// {
// *d = p->data[p->pop];
// return 0;
// }
// else
// return 1;
//}
//
////运算符出栈
//int PopSOP(SOP * p, char * c)
//{
// (p->pop)--;
// if(p->pop >= 0)
// {
// *c = p->op[p->pop];
// return 0;
// }
// else
// return 1;
//}
//
////从s[*pc]开始获取一个浮点数
//int StrToInt(char s[], int * pc, float *pout)
//{
// char buf[100];
// int i = 0;
//
// if(s[*pc]<'0' || s[*pc]>'9')
// return 1;
// else
// {
// while((s[*pc] >= '0' && s[*pc] <= '9') || s[*pc] == '.')
// {
// buf[i] = s[*pc];
// (*pc)++;
// i++;
// }
// buf[i] = '\0';
// *pout = (float)atof(buf);
// return 0;
// }
//}
//
////从s[*pc]获取一个char
//int StrToChar(char s[], int *pc, char *pout)
//{
// if('+'==s[*pc]||'-'==s[*pc]||'*'==s[*pc]||'/'==s[*pc]||'('==s[*pc]||')'==s[*pc])
// {
// *pout = s[*pc];
// (*pc)++;
// return 0;
// }
// else
// return 1;
//}
//
////获取优先级
//char GetPri(char c1, char c2)
//{
//
// char f[7][7] = {'>', '>', '<', '<', '<', '>', '>',
// '>', '>', '<', '<', '<', '>', '>',
// '>', '>', '>', '>', '<', '>', '>',
// '>', '>', '>', '>', '<', '>', '>',
// '<', '<', '<', '<', '<', '=', '\0',
// '>', '>', '>', '>', '\0', '>', '>',
// '<', '<', '<', '<', '<', '\0', '=',
// };
//
// int i=0, j=0;
// switch(c1)
// {
// case '+':
// i = 0;
// break;
// case '-':
// i = 1;
// break;
// case '*':
// i = 2;
// break;
// case '/':
// i = 3;
// break;
// case '(':
// i = 4;
// break;
// case ')':
// i = 5;
// break;
// case '=':
// i = 6;
// break;
// }
// switch(c2)
// {
// case '+':
// j = 0;
// break;
// case '-':
// j = 1;
// break;
// case '*':
// j = 2;
// break;
// case '/':
// j = 3;
// break;
// case '(':
// j = 4;
// break;
// case ')':
// j = 5;
// break;
// case '=':
// j = 6;
// break;
// }
// return f[i][j];
//}
//
////计算表达式
//float Operate(float a, char op, float b)
//{
// switch(op)
// {
// case '+':
// return a + b;
// case '-':
// return a - b;
// case '*':
// return a * b;
// case '/':
// return a / b;
// default:
// return 0;
// }
//}
//
//int main(void)
//{
// char s[10][1000];
// int c = 0;
// float bufda;
// char bufop;
// float a, b;
// SDA sda;
// SOP sop;
// int n;
// int i;
//
// scanf("%d", &n);
// for(i = 0; i < n; i++)
// scanf("%s", s[i]);
// for(i = 0; i < n; i++)
// {
// c = 0;
// InitSDA(&sda); //初始化数据栈
// InitSOP(&sop); //初始化符号栈
// while(s[i][c] != '=' || sop.op[sop.pop - 1] != '=') // 计算未完成
// {
// if(0 == StrToInt(s[i], &c, &bufda))
// PushSDA(&sda, bufda); //数据入栈
// else
// {
// switch(GetPri(sop.op[sop.pop - 1], s[i][c]))
// {
// case '<':
// if(0 == StrToChar(s[i], &c, &bufop))
// PushSOP(&sop, bufop);
// break;
// case '=':
// PopSOP(&sop, &bufop);
// c++;
// break;
// case '>':
// PopSOP(&sop, &bufop);
// PopSDA(&sda, &b);
// PopSDA(&sda, &a);
// PushSDA(&sda, Operate(a, bufop, b));
// break;
// }
// }
// }
// PopSDA(&sda, &a);
// printf("%.2f\n", a);
// }
// return 0;
//}
//
//C++
//#include<queue>
//#include<stack>
//#include<vector>
//#include<math.h>
//#include<cstdio>
//#include<sstream>
//#include<numeric>//STL数值算法头文件
//#include<stdlib.h>
//#include <ctype.h>
//#include<string.h>
//#include<iostream>
//#include<algorithm>
//#include<functional>//模板类头文件
//using namespace std;
//
//const int INF=0x3f3f3f3f;
//const int maxn=110000;
//typedef long long ll;
//
//int priority(char c)
//{
// if(c == '=') return 0;
// if(c == '+') return 1;
// if(c == '-') return 1;
// if(c == '*') return 2;
// if(c == '/') return 2;
// return 0;
//}
//
//void compute(stack<double>& Num,stack<char>& Op)
//{
// double b = Num.top();
// Num.pop();
// double a = Num.top();
// Num.pop();
// switch(Op.top())
// {
// case '+':
// Num.push(a+b);
// break;
// case '-':
// Num.push(a-b);
// break;
// case '*':
// Num.push(a*b);
// break;
// case '/':
// Num.push(a/b);
// break;
// }
// Op.pop();
//}
//
//int main()
//{
// int z;
// char str[1005];
// stack<double> Num;
// stack<char> Op;
// scanf("%d",&z);
// while(z--)
// {
// scanf("%s",str);
// int len = strlen(str);
// for(int i=0; i<len; i++)
// {
// if(isdigit(str[i]))
// {
// double n = atof(&str[i]);
// while(i<len && (isdigit(str[i]) || str[i]=='.'))
// i++;
// i--;
// Num.push(n);
// }
// else
// {
// if(str[i] == '(')
// Op.push(str[i]);
// else if(str[i] == ')')
// {
// while(Op.top()!='(')
// compute(Num,Op);
// Op.pop();
// }
// else if(Op.empty() || priority(str[i])>priority(Op.top()))
// Op.push(str[i]);
// else
// {
// while(!Op.empty() && priority(str[i])<=priority(Op.top()))
// compute(Num,Op);
// Op.push(str[i]);
// }
// }
// }
// Op.pop();
// printf("%.2f\n",Num.top());
// Num.pop();
// }
// return 0;
//}