题意:输入一个算术表达式,求值(数字为整数,但结果不一定是整数,不存在不合法的输入)。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237
——>>这是中缀表达式的运算。开两个栈,一个用来存操作数,一个用来存运算符。定义3个级别,# 的级别最低,+ 和 - 的级别相同且高于 #,* 和 / 的级别相同且高于 + 和 - ,先往运算符栈放入一个 # ,表达式最后也加一个 #,读表达式,若读到数字,则以数字类型输入,直接放入操作数栈,若读到的是运算符,则比较读到的运算符与运算符栈顶符号的级别,若比栈顶的高,则入栈,否则,从数栈取两个操作数进行运算符栈顶元素的运算,再把结果压入数栈,刚刚读到的运算符再与现在运算符栈顶元素的级别进行比较……最后数剩下的一个元素,就是结果。
#include <iostream>
#include <cstdio>
#include <stack>
#include <cstring>
using namespace std;
int r(char c) //级别
{
switch(c)
{
case '#': return 0;
case '+': return 1;
case '-': return 1;
case '*': return 2;
case '/': return 2;
default: return -1;
}
}
double cal(double a, double b, char c) //运算
{
switch(c)
{
case '+': return a+b;
case '-': return a-b;
case '*': return a*b;
case '/': return a/b;
default: return -1;
}
}
int main()
{
char s[210];
int i;
while(cin.getline(s, sizeof(s)))
{
if(strcmp(s, "0") == 0) return 0;
int len = strlen(s);
s[len++] = ' ';
s[len++] = '#';
s[len] = 0;
stack<char> f;
stack<double> dit;
f.push('#');
for(i = 0; i < len; i++)
{
if(s[i] == ' ') continue;
if(isdigit(s[i])) //是数字
{
double temp;
sscanf(s+i, "%lf", &temp); //以数字类型输入,开始没注意到两位及两位以上的整数,WA了1次!
dit.push(temp);
while(isdigit(s[i+1])) i++;
}
else //是符号
{
bool ok = 1;
while(ok)
{
if(r(s[i]) > r(f.top()))
{
f.push(s[i]);
ok = 0;
}
else
{
if(s[i] == '#' && f.top() == '#') break; //结束
double b = dit.top(); dit.pop();
double a = dit.top(); dit.pop();
char c = f.top(); f.pop();
double d = cal(a, b, c);
dit.push(d);
}
}
}
}
double ret = dit.top();
printf("%.2lf\n", ret);
while(!f.empty()) f.pop();
while(!dit.empty()) dit.pop();
}
return 0;
}