NYOJ 35 表达式求值 (栈 stack)


表达式求值

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入
第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出
每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入
2
1.000+2/4=
((1+2)*5+1)/4=
样例输出
1.50
4.00

原文地址:http://blog.csdn.net/piaoyi0208/article/details/7822686

题意:给一个中缀表达式 求出表达式的值

操作符优先级:(从大到小) ‘(’ ——   ‘ * ’ 或 ‘ / ’ ——   '+'  或  ‘-’ ——  ‘ )’  ;(把括号也看作操作符)

思路:用两个栈,一个操作符栈,一个数据栈,顾名思义,数据栈存表达式的数据,操作符栈存 ()+ - * /  等。将中缀表达式转换为后缀表达式,在转换的过程中求表达式的值!具体步骤如下:(下面思路假设数据都是一位数的整数,便于理解,具体数字处理在代码中体现)

先将 一个’=‘ 放入 操作符栈

1:读取表达式的一个字符;

2:   若为数字存入数据 栈 转至1;

3:若为操作符:比较操作符栈顶 和 该操作符的 优先级  

      ① pk函数返回值 为 ’>‘(若操作符栈顶优先级大于或等于该操作符的优先级):栈顶操作符出栈(假设操作符为-) ,从数据栈出两个数据(假设第一个是y,第二个 是x),计算值(x-y),注意数据顺序!!将值放入 数据栈!转至 3;

      ② pk函数返回值为’<‘    (若操作符栈顶优先级小于该操作符的优先级):  讲该 操作符放入 操作符栈,转至 1;

      ③ pk函数返回值为’=‘    (具体看代码) 将操作符栈顶的操作符出栈,转至1;

4:输出数据栈栈顶值即可!

 
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <stack>
using namespace std;

int n;
char str[1010];
char ok[220];
int end, loop;
int len;
char pk(char c1, char c2)
{
    if (c1 == '+' || c1 == '-'){
        if (c2 == '+' || c2 == '-' || c2 == ')' || c2 == '=')
            return '>';
        else
            return '<';
    }
    else if (c1 == '*' || c1 == '/'){
        if (c2 == '+' || c2 == '-' || c2 == '*' || c2 == '/' || c2 == ')' || c2 == '=')
            return '>';
        else
            return '<';
    }
    else if (c1 == '(' || c1 == '='){
        if ((c1 == '(' && c2 == ')') || (c1 == '=' && c2 == '='))
                return '=';
        else
            return '<';
    }
}

double oper(double x, char c, double y)
{
    if (c == '+') return x + y;
    else if (c == '-') return x - y;
    else if (c == '*') return x * y;
    else return x / y;
}

int main()
{
    cin >> n;
    while (n--){
        end = 0, loop = 0;
        stack<char> sc;
        sc.push('=');
        stack<double> s;
        cin >> str;
        len = strlen(str);
        for (int i = 0; i < len;){
            if (str[i] == '=' && sc.top() == '=')
                break;
            if (isdigit(str[i]) || str[i] == '.'){
                ok[end++] = str[i];
                loop = 1;
                i++;
                continue;
            }
            if (loop){
                ok[end] = '\0';
                double x = atof(ok);     //把字符串转换成浮点数值
                end = 0, loop = 0;
                s.push(x);
            }
            switch(pk(sc.top(), str[i])){
                case '<': sc.push(str[i]); i++; break;
                case '=': sc.pop(); i++; break;
                case '>':
                    double  x, y;
                    y = s.top();
                    s.pop();
                    x = s.top();
                    s.pop();
                    char c = sc.top();
                    sc.pop();
                    s.push(oper(x, c, y));
                    break;
            }
        }
        cout << setprecision(2) << fixed << s.top() << endl;
    }
    return 0;
}
        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值