四则运算(可含括号)表达式求值问题

算法学习第六篇

输入一个行数再在每行输入一个表达式,得出结果,这是一道非常经典的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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值