题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=35
本题是求算数表达式的值。操作数是大于等于的实数,操作符有 + ,- ,*,/,()
只要开两个栈,一个记录操作符,一个记录后缀表达式。
即:把原始的中缀表达式转换成后缀表达式(逆波兰式),然后进行计算。
前缀和后缀表示法有三项公共特征:
操作数的顺序与等价的中缀表达式中操作数的顺序一致
不需要括号
操作符的优先级不相关
中缀转化为后缀算法:
a. 得到一操作符或操作数;
b. 若输入为操作数,则输出到数组,转a;
c. 若输入为‘(’,压栈,转a;
d. 若输入为‘)’,栈顶出栈,输出到数组,直至栈顶为‘(’,不输出到数组(抛弃),转a;
e. 若输入为操作符,
若栈空或栈顶为‘(’或操作符.忧先级大于栈顶操作符,压栈,转a
若操作符优先级小于栈顶操作符,则出栈,输出至数组,转e;
d. 若输入结束,出栈,输出到数组,直至栈空。
具体转换方法,参考:http://blueve.me/archives/318
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <string>
using namespace std;
int priority[100];
//初始化操作符优先级
void initPri()
{
priority['('] = 1;
priority['+'] = 2;
priority['-'] = 2;
priority['*'] = 3;
priority['/'] = 3;
}
//a是符号栈顶,b是当前判断符号
//a>=b,返回true;a<b,返回false
bool judgeOpePri(char a,char b)
{
return priority[a] >= priority[b] ? true : false;
}
//两个参数:中缀表达式,生成的后缀表达式
void convert(string infixExp,stack<string> &postfixExp)
{
//运算符栈
stack<char> opS;
//临时操作数
string digitTemp;
//临时操作符
string operTemp;
int len = infixExp.length();
bool hasDigit = false;
//过滤掉'='
for(int i=0; i<len-1;)
{
//如果是操作数的一部分
while((isdigit(infixExp[i]) || infixExp[i] == '.') && i<len-1)
{
hasDigit = true;
digitTemp.push_back(infixExp[i]);
i++;
}
if(hasDigit == true)
{
postfixExp.push(digitTemp);
digitTemp = "";
hasDigit = false;
}
else
{
//如果操作符栈是空的,就入栈
if(opS.empty())
{
opS.push(infixExp[i]);
i++;
}
//注意对于'('同等优先级是不起作用的
else if(infixExp[i] == '(')
{
opS.push(infixExp[i]);
i++;
}
//弹出"()"之内的所有运算符
else if(infixExp[i] == ')')
{
while(!opS.empty())
{
char c = opS.top();
operTemp = "";
operTemp.push_back(c);
opS.pop();
if(c == '(')
{
break;
}
else
{
postfixExp.push(operTemp);
}
}
i++;
}
//操作符栈顶的优先级大
else if(judgeOpePri(opS.top(),infixExp[i]) == true)
{
char c = opS.top();
operTemp = "";
operTemp.push_back(c);
opS.pop();
postfixExp.push(operTemp);
//注意此时不要i++,因为还要继续比较
}
//操作符栈顶的优先级小
else
{
opS.push(infixExp[i]);
i++;
}
}
}
//清空符号栈
while(!opS.empty())
{
char c = opS.top();
operTemp = "";
operTemp.push_back(c);
opS.pop();
postfixExp.push(operTemp);
}
}
double answerQ(stack<string> &postfixExp)
{
stack<string> couterFix;
stack<double> resultSta;
while(!postfixExp.empty())
{
couterFix.push(postfixExp.top());
postfixExp.pop();
}
double a,b;
while(!couterFix.empty())
{
string c = couterFix.top();
double d;
couterFix.pop();
int cas = 5;
if(strcmp(c.c_str(),"+") == 0) cas = 0;
else if(strcmp(c.c_str(),"-") == 0) cas = 1;
else if(strcmp(c.c_str(),"*") == 0) cas = 2;
else if(strcmp(c.c_str(),"/") == 0) cas = 3;
if(cas!=5)
{
double a = resultSta.top();
resultSta.pop();
double b = resultSta.top();
resultSta.pop();
switch(cas)
{
case 0:
{
resultSta.push(b + a);
break;
}
case 1:
{
resultSta.push(b - a);
break;
}
case 2:
{
resultSta.push(b * a);
break;
}
case 3:
{
resultSta.push(b / a);
break;
}
default:
{}
}
}
else
{
sscanf(c.c_str(),"%lf",&d);
resultSta.push(d);
}
}
return resultSta.top();
}
int main()
{
/*#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif*/
int n;
scanf(" %d",&n);
initPri();
while(n--)
{
string infixExp;
stack<string> postfixExp;
cin>>infixExp;
convert(infixExp,postfixExp);
double ans = answerQ(postfixExp);
printf("%.2lf\n",ans);
}
return 0;
}