NYOJ-35 表达式求值
2012-08-02 23:57
330 查看
表达式求值
时间限制:3000 ms | 内存限制:65535 KB难度:4
描述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
/* 功能Function Description: 利用栈实现中序表达式 NYOJ-35 开发环境Environment: DEV C++ 4.9.9.1 技术特点Technique: 版本Version: 作者Author: 可笑痴狂 日期Date: 20120802 备注Notes: 表达式 输入'='结束 支持浮点数 注意: 用exit(0) 提交会显示编译错误,没有<conin.h>头文件 */ #include<cstdio> #include<iostream> #include<stack> #include<cctype> #include<cmath> //#include<conio.h> //exit(0);退出程序包含在#include<conio.h> #include<stdlib.h> //#include<cstdlib> using namespace std; stack<double> Opnd; //操作数栈 stack<char> Optr; //运算符栈 void Init() //栈的初始化 { while(!Opnd.empty()) Opnd.pop(); while(!Optr.empty()) Optr.pop(); Optr.push('='); //先压入一个结束符‘=’ } char Precede(char i,char j) //判断i和j的优先级 { switch(i) { case '+': case '-': if(j=='+'||j=='-'||j==')'||j=='=') return '>'; else return '<'; case '*': case '/': if(j=='(') return '<'; else return '>'; case '(': if(j==')') return '='; // else if(j=='=') // exit(0); else return '<'; case ')': // if(j=='(') // exit(0); // else return '>'; case '=': if(j=='=') return '='; // else if(j==')') // exit(0); else return '<'; } // exit(0); } double Operate(double a,char i,double b) //计算 { switch (i) { case '+': return a+b; case '-': return a-b; case '*': return a*b; case '/': return a/b; } } int judge(char c) //判断---如果c为数字则返回1;若为小数点则返回2;如果c为操作符或者结束符则返回0;; { if(isdigit(c)) return 1; else if(c=='.') return 2; else return 0; } double EvaluateExpression(char *p) { double a,b,temp; int flag; char *st,*end,c,theta; //定义操作符theta Init(); c=*p; while(c!='='||Optr.top()!='=') //即当操作符栈和当前读入的字符都是‘=’时结束循环 { if(isdigit(c)) //isdigit(c) 如果c是数字,则返回true; isalpha(c) 如果c是字母,则为true; { temp=0; flag=0; for(;judge(c);c=*(++p)) //当不是数字或小数点时结束循环 { if(judge(c)==1) //说明是数字 { temp=temp*10+c-'0'; if(c!=0) end=p; } else //说明是小数点 { st=p; //记录下小数点的位置 end=p; //记录小数点后最后一个非零数字的位置 flag=1; //标记有小数点 } } if(flag) //调整小数点的位置 temp=temp/pow(10,end-st); Opnd.push(temp); //记录的数字进栈 } else { switch(Precede(Optr.top(),c)) { case '<': //栈顶元素优先权低 Optr.push(c); c=*(++p); break; case '>': //栈顶元素优先权高---退栈并将运算结果入栈 theta=Optr.top(); Optr.pop(); a=Opnd.top(); Opnd.pop(); b=Opnd.top(); Opnd.pop(); Opnd.push(Operate(b,theta,a)); break; case '=': //脱括号并接收下一字符 Optr.pop(); c=*(++p); } } } return Opnd.top(); } int main() { int T; char s[1000]; scanf("%d",&T); while(T--) { scanf("%s",s); printf("%.2lf\n",EvaluateExpression(s)); } return 0; }
/* 功能Function Description: 利用栈实现中序表达式 开发环境Environment: DEV C++ 4.9.9.1 技术特点Technique: 版本Version: 作者Author: 可笑痴狂 日期Date: 20120802 备注Notes: 表达式 输入'#'结束 只能处理整数之间的运算 */ #include<cstdio> #include<iostream> #include<stack> #include<cctype> using namespace std; stack<int> Opnd; //操作数栈 stack<char> Optr; //运算符栈 void Init() { while(!Opnd.empty()) Opnd.pop(); while(!Optr.empty()) Optr.pop(); Optr.push('#'); //将表达式起始符 } char Precede(char i,char j) { switch(i) { case '+': case '-': if(j=='+'||j=='-'||j==')'||j=='#') return '>'; else return '<'; case '*': case '/': if(j=='(') return '<'; else return '>'; case '(': if(j==')') return '='; else if(j=='#') exit(0); else return '<'; case ')': if(j=='(') exit(0); else return '>'; case '#': if(j=='#') return '='; else if(j==')') exit(0); else return '<'; } exit(0); } int Operate(int a,char i,int b) { switch (i) { case '+': return a+b; case '-': return a-b; case '*': return a*b; case '/': return a/b; } } int EvaluateExpression(char *p) { int a,b,temp; char c,theta; //定义操作符theta Init(); c=*p; while(c!='#'||Optr.top()!='#') { if(isdigit(c)) //isdigit(c) 如果c是数字,则返回true; isalpha(c) 如果c是字母,则为true; { temp=0; for(;isdigit(c);c=*(++p)) temp=temp*10+(c-'0'); Opnd.push(temp); //检测到有运算符,先把记录的数字进栈 } else { switch(Precede(Optr.top(),c)) { case '<': //栈顶元素优先权低 Optr.push(c); c=*(++p); break; case '>': //栈顶元素优先权高---退栈并将运算结果入栈 theta=Optr.top(); Optr.pop(); a=Opnd.top(); Opnd.pop(); b=Opnd.top(); Opnd.pop(); Opnd.push(Operate(b,theta,a)); break; case '=': //脱括号并接收下一字符 Optr.pop(); c=*(++p); } } } return Opnd.top(); } int main() { int T; char s[1000]; scanf("%d",&T); while(T--) { scanf("%s",s); printf("%d\n",EvaluateExpression(s)); } return 0; }
相关文章推荐
- NYOJ-35-表达式求值
- nyoj 35 表达式求值(栈)
- NYOJ 35 表达式求值(栈)
- nyoj 题目35 表达式求值
- nyoj 35 表达式求值
- NYOJ 35 表达式求值 (中缀表达式 小数 带括号)
- NYOJ 35表达式求值
- NYOJ - 35 表达式求值
- nyoj35表达式求值
- nyoj 35 表达式求值(栈)
- NYOJ 35 表达式求值(非递归+栈)
- nyoj35——表达式求值
- 南阳 oj 表达式求值 题目35 数据结构 NYOj
- nyoj 35 表达式求值(栈)
- NYOJ35——表达式求值
- 【表达式求值】中缀表达式变后缀+后缀表达式的求法 (NYOJ 35+NYOJ 1272表达式求值)
- nyoj35 表达式求值
- nyoj 35 表达式求值<模拟+栈>
- NYOJ 35 表达式求值
- NYOJ 35 表达式求值