算法学习第六篇
输入一个行数再在每行输入一个表达式,得出结果,这是一道非常经典的OJ题目,有一定的难度,CCF中也出现过类似的题目,大同小异,此题目难点集中在以下几点:
1.判断符号优先级
2.考虑括号问题
3.字符串如何计算,涉及到栈的灵活运用
4.结果的格式问题
输入表达式输出结果,如果是小数则保留两位小数,四舍五入,整数运算直接取整
输入:
3
1+2
2.7/3
1+3*3
输出:
3
0.90
10
代码如下:
#include <iostream>
#include <string>
#include <iomanip>
#include <stack>
using namespace std;
//判断符号优先级
int judge(char c1,char c2)
{
int a1,a2;
if('+'==c1||'-'==c1) a1=3;
if('*'==c1||'/'==c1) a1=5;
if('('==c1) a1=1;
if(')'==c1) a1=7;
if('#'==c1) a1=0;
if('+'==c2||'-'==c2) a2=2;
if('*'==c2||'/'==c2) a2=4;
if('('==c2) a2=6;
if(')'==c2) a2=1;
if('#'==c2) a2=0;
if(a1>a2) return 1;
if(a1==a2) return 0;
if(a1<a2) return -1;
}
//符号判别函数
double run(char c,double d1,double d2)
{
switch(c)
{
case'+':
return d1+d2;
break;
case'-':
return d1-d2;
break;
case'*':
return d1*d2;
break;
case'/':
return d1/d2;
break;
default:
break;
}
}
//字符串计算函数
double calculate(string str)
{
const char *op="+-*/()#";
str.append(1,'#');
stack<char> optr;//操作符栈
stack<double> opnd;//操作数栈
int a=-1;
optr.push('#');
while(true)
{
int b=a+1;
a=str.find_first_of(op,a+1);
if(a==string::npos) break;
if(a!=b)
{
string ss(str,b,a-b);
double d=atof(ss.c_str());
opnd.push(d);
}
int ju=judge(optr.top(),str[a]);
if(-1==ju)
{
optr.push(str[a]);
}
if(0==ju)
{
optr.pop();
}
if(1==ju)
{
double d1=opnd.top();
opnd.pop();
double d2=opnd.top();
opnd.pop();
d1=run(optr.top(),d2,d1);
opnd.push(d1);
optr.pop();
a--;
}
}
str.erase(str.length()-1,1);
return opnd.top();
}
int main()
{
int n;
cin>>n;
while(n>0)
{
string s;
cin>>s;
double t=calculate(s);
int m=(t*10)/10;
if(m==t)
{
cout<<m<<endl;
}
else
{
cout<<fixed<<setprecision(2)<<t<<endl;
}
n--;
}
system("pause");
return 0;
}