HDU1237简单计算器-中缀表达式-后缀表达式

来源:互联网 发布:泰迪狗鞋子淘宝网 编辑:程序博客网 时间:2024/05/16 04:49

简单计算器

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11355    Accepted Submission(s): 3697

Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。 
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 24 + 2 * 5 - 7 / 110
Sample Output
3.0013.36
Source
浙大计算机研究生复试上机考试-2006年
 
思路:
        对于中缀表达式的运算一般要转化成后缀表达式再作运算,开两个栈,一个作为操作数栈StackDigital,一个作为操作符栈StackOperator。
1.定义一个函数判定优先级:# 的优先级最低,为0,+ 和 - 的级别相同且高于 #,标为1,* 和 / 的级别相同且高于 + 和 - ,标志为2,
2.先往运算符栈放入一个 # (标定界限),表达式最后也加一个 #( (标定界限)),
3.遍历表达式,若读到数字,则以数字类型输入,直接放到操作数栈,若读到的是运算符,则比较读到的运算符与运算符栈顶符号的级别,
若比栈顶的高,则入栈,否则,从数栈取两个操作数根据操作符栈顶的操作进行运算,再把结果压入数栈,刚刚读到的运算符再与现在运算符栈
顶元素的级别进行比较……最后数剩下的一个元素,就是结果。
#include <iostream>#include <cstdio>#include <string.h>#include <ctype.h>using namespace std;double stDit[300];char stOp[300],str[300];int top1,top2;int Priority(char op){if (op=='#') return 0;if (op=='+' || op=='-') return 1;if (op=='*' || op=='/')return 2;elsereturn -1;}double Operate(double x,double y,char op){if (op=='+') return x+y;if (op=='-') return x-y;if (op=='*') return x*y;if (op=='/') return x/y;else return -1;}double Calc(){double x,y,tmp;char op;int i,n = strlen(str);top1 = top2 = -1;stOp[++top2] = '#';str[n++] = '#';for(i=0; i < n; ++i){if (str[i]==' ')continue;if (isdigit(str[i]))//是数字{sscanf(str+i,"%lf",&tmp);stDit[++top1] = tmp;//stack pushwhile(isdigit(str[i+1]))//+1很重要++i;}else//是操作符{while (Priority(stOp[top2]) >= Priority(str[i]))//如果操作栈顶的操作符优先级高,则作+-*/运算{if (str[i]=='#' && stOp[top2]=='#')return stDit[top1];y = stDit[top1--];x = stDit[top1--];op = stOp[top2--];stDit[++top1] = Operate(x,y,op);}stOp[++top2] = str[i];//如果新操作符优先级高,str[i]进栈}}return stDit[top1];}int main(){int i;while (gets(str) != NULL && strcmp(str,"0")!=0){printf("%.2lf\n",Calc());}return 0;}


0 0
原创粉丝点击