未完待更新.......
推荐讲解:前缀、中缀、后缀表达式
例题:HDU1237 简单计算器(不含括号处理)
简单计算器
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 20966 Accepted Submission(s): 7490
Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2 4 + 2 * 5 - 7 / 11 0
Sample Output
3.00 13.36
【分析】:
用两个栈分别处理运算符和数字,运算过程主要是把中缀表达式转化为后缀表达式
【代码】:
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
stack<char> s1;
stack<double> s2;
char s[230];
char fir[128];
void init()
{
fir['(']=0;//优先级小,后运算
fir['+']=fir['-']=1;
fir['*']=fir['/']=2;
fir[')']=0;//右括号无所谓,因为单独处理
}
double result(double a,double b,char ch)//计算结果
{
if(ch=='+') return a+b;
if(ch=='-') return a-b;
if(ch=='*') return a*b;
if(ch=='/') return a/b;
}
int calcu()//从符号栈拿一个字符到数字栈计算
{
if(!s1.empty())//把s1中的符号计算
{
double num1=s2.top();s2.pop();
double num2=s2.top();s2.pop();
s2.push(result(num2,num1,s1.top()));//注意num1,num2顺序
s1.pop();
return 1;//成功计算
}
return 0;
}
int main()
{
init();//定义运算符优先级
while(gets(s),s[0]!='0'||strlen(s)>1)
{
while(!s2.empty())s2.pop();
while(!s1.empty())s1.pop();//清空栈
for(int i=0;s[i];i++)
{
if(s[i]==' ')continue;
if(s[i]>='0'&&s[i]<='9')//把数字转入s2
{
double num=0;
while(s[i]>='0'&&s[i]<='9')
num=num*10+s[i++]-'0';
s2.push(num);
i--;//要与for循环的i++抵消一下
}
else //遇到符号
{
if(s1.empty() || fir[s[i]]>fir[s1.top()])//运算符递增时,加入栈
s1.push(s[i]);
else if(s[i]==')')//遇到右括号,它与左括号间的运算符全部取出
{
while(s1.top()!='(')
calcu();
s1.pop();//把左括号扔掉
}
else
{
while(!s1.empty() && fir[s[i]]<=fir[s1.top()])//把s1中的符号计算
calcu();
s1.push(s[i]);//把新运算符加入栈
}
}
}
while(calcu());//剩余的符号处理完
printf("%.2lf\n",s2.top());
}
return 0;
}