问题 C: 某计算器的超电磁炮(加减乘除括号表达式求值)

时间限制: 1 Sec内存限制: 64 MB提交: 510解决: 156
提交状态
题目描述
输入由非负整数、+、-、*、/、(、)组成的计算表达式,计算该表达式的值。

输入
每个输入文件中一组数据。

输入只有一行,不超过200个字符,其中不存在空格。数据保证表达式一定合法,且所有的整数都不小于0、不大于1024。中间结果保证不超过15位有效数位精度。

输出
输出一行,即表达式的值,结果精度保留小数点后2位。

样例输入
3+(12/(2*2+1))
样例输出
5.40
提示

此题是数据结构课本上的原题,可用栈来做(符号有+-*/()#)
首先读取到的是数字,则进数字栈若不是则考虑各个符号的优先顺序(假设#是符号栈的栈底,只有当读取到末尾的#号时才出栈)
当读取符号为+或者-时,只有栈顶是(、#才进栈,其余出栈
当读取符号为*或者/时,只有栈顶是(、#、+、-才进栈,其余出栈
当读取符号为(进栈
当读取符号为)时,除了(都出栈,且遇到(实施的是脱括号操作
当读取符号为#时,除了#都出栈,且遇到#实施的是类似脱括号操作
下面是代码

#include<iostream>
#include<string>
#include<vector>
#include<cctype>
using namespace std;
int compare(char x, char y)
{
    if ((x == '#'&&y == '#')||(x == ')' && y == '(')) return 0;//脱括号
    if (x == '(' || (string("+-").find(x) < 2 && string("(#").find(y)<2) || (string("*/").find(x) < 2 && string("(+-#").find(y) < 4)) return 1;//进栈
    return -1;//出栈

}
int main()
{
    vector<char> oper;
    vector<double> oped;
    string s;
    cin >> s;
    s.push_back('#');//结尾放个结束符#
    int t = 0;
    oper.push_back('#');//开头放开始符#
    while (!oper.empty())
    {
        if (isdigit(s[t]))//是数字
        {
            int te = t;
            while (isdigit(s[t]))//知道第t位置不是数字,此时t位置正好是非数字位
                t++;
            oped.push_back(stod(string(s, te, t - te)));//开始位置到t的前一位置转换了double,
        }
        else
        {
            int temp = compare(s[t], oper.back());//判断优先顺序
            if (temp == 1) oper.push_back(s[t++]);//进栈
            else if (temp == 0) { oper.pop_back();t++; }//脱括号
            else//出栈
            {
                double tt;
                switch (oper.back()) {
                case '+':tt = oped[oped.size() - 2] + oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
                    break;
                case '-':tt = oped[oped.size() - 2] - oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
                    break;
                case '*':tt = oped[oped.size() - 2] * oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
                    break;
                case '/':tt = oped[oped.size() - 2] / oped.back();oped.pop_back();oped.pop_back();oped.push_back(tt);
                    break;
                }
                oper.pop_back();
            }
        }
    }
    printf("%.2f\n", oped.back());//输出结果
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值