NYOJ35 表达式求值

表达式求值

时间限制: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
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iomanip>
using namespace std;

class OPTR   //运算符栈
{
private:
    char s[1001];
    int length;

public:
    OPTR()
    {
        length = -1;
    }

    char pop()
    {
        return s[length--];
    }

    void push(char c)
    {
        s[++length] = c;
    }

    char get_top()
    {
        return s[length];
    }

    void clear()
    {
        length = -1;
    }
};

class OPND  //操作数栈
{
private:
    double a[1001];
    int length;

public:
    OPND()
    {
        length = -1;
    }

    double pop()
    {
        return a[length--];
    }

    void push(double b)
    {
        a[++length] = b;
    }

    double get_top()
    {
        return a[length];
    }

    void clear()
    {
        length = -1;
    }
};

double operate(double a, double b, char c)  //根据符号进行相应的运算
{
    double result;
    if (c == ‘+‘)
        result = a + b;

    else if (c == ‘-‘)
        result = a - b;

    else if (c == ‘*‘)
        result = a*b;

    else if (c == ‘/‘)
        result = a / b;

    return result;
}

int get_position(char c)  //获取符号的下标
{
    char s[] = { ‘+‘,‘-‘,‘*‘,‘/‘,‘(‘,‘)‘,‘=‘ };
    int i;
    int length;
    int position;

    position = -1;
    length = strlen(s);
    for (i = 0;i < length;i++)
    {
        if (s[i] == c)
        {
            position = i;
            break;
        }
    }

    return position;
}

char precede[][8]=    //优先级表
{
    {‘>‘,‘>‘,‘<‘,‘<‘,‘<‘,‘>‘,‘>‘},
    {‘>‘,‘>‘,‘<‘,‘<‘,‘<‘,‘>‘,‘>‘},
    {‘>‘,‘>‘,‘>‘,‘>‘,‘<‘,‘>‘,‘>‘},
    {‘>‘,‘>‘,‘>‘,‘>‘,‘<‘,‘>‘,‘>‘},
    {‘<‘,‘<‘,‘<‘,‘<‘,‘<‘,‘=‘,‘ ‘},
    {‘>‘,‘>‘,‘>‘,‘>‘,‘ ‘,‘>‘,‘>‘},
    {‘<‘,‘<‘,‘<‘,‘<‘,‘<‘,‘ ‘,‘=‘}
};

bool in(char c)   //判断是不是操作数
{
    char s[] = { ‘+‘,‘-‘,‘*‘,‘/‘,‘(‘,‘)‘,‘=‘ };
    int i;
    int length;

    length = strlen(s);
    for (i = 0;i < length;i++)
    {
        if (s[i]==c)
            break;
    }

    if (i<length)
        return true;

    else
        return false;
}

int main()
{
    char s[1001];
    char temp[1001];
    int i;
    int j;
    int k;
    OPTR optr;
    OPND opnd;
    char top;
    int flag;
    int l;
    double a;
    double b;
    int length;
    int T;

    cin >> T;
    while (T--)
    {
        optr.clear();
        opnd.clear();
        optr.push(‘=‘);   //让第一个操作符与‘=‘比较

        cin >> s;
        length = strlen(s);
        l = 0;
        flag = 0;
        for (i = 0;i<length;i++)
        {
            if (s[i] == ‘=‘ && optr.get_top() == ‘=‘)   //终止条件
                break;

            if (in(s[i]) == false)
            {
                temp[l++] = s[i];
                flag = 1;
            }

            else
            {
                if (flag == 1)
                {
                    temp[l] = ‘\0‘;
                    flag = 0;
                    l = 0;

                    a = atof(temp);
                    opnd.push(a);
                }

                top = optr.get_top();
                j = get_position(top);
                k = get_position(s[i]);

                if (precede[j][k] == ‘<‘)
                {
                    optr.push(s[i]);
                }

                else if (precede[j][k] == ‘=‘)
                {
                    optr.pop();
                }

                else if (precede[j][k] == ‘>‘)
                {
                    b = opnd.pop();
                    a = opnd.pop();
                    optr.pop();

                    a = operate(a, b, top);
                    opnd.push(a);
                    i--;
                }
            }
        }
        cout << setiosflags(ios::fixed) << setprecision(2) << opnd.get_top() << endl;
    }
    return 0;
}

时间: 2024-10-31 23:50:55

NYOJ35 表达式求值的相关文章

NYOJ35 表达式求值 【栈】

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:"1+2/4=",程序就输出1.50(结果保留两位小数) 输入 第一行输入一个整数n,共有n组测试数据(n<10). 每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以"

nyoj35表达式求值

/*注意各个符号的优先级,建议看懂符号的优先级后在看代码.有助于你理解:以下为代码*/ #include<stdio.h> #include<string.h> #include<stack> #include<algorithm> #include<stdlib.h> using namespace std; double zhao1(double a,char op,double b) { switch(op) { case '+':retu

【NYOJ-35】表达式求值——简单栈练习

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,最近又学会了一些简单的函数求值,比如,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等.经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式. 假设表达式可以简单定义为: 1. 一个正的十进制数 x 是一个表达式. 2. 如果 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x,y

四则运算表达式求值 OpenJ_Bailian - 4132

四则运算表达式求值 OpenJ_Bailian - 4132 题意:设计一个计算器,实现+-*/以及()的表达式运算求值. 栈的应用,这学期学数据结构,手写了栈练一下~ 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=10010; //最大表达式长度 4 5 template <typename T> 6 class Stack; 7 8 template <typename T> 9

表达式求值

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 Dr.Kong设计的机器人卡多掌握了加减法运算以后,近期又学会了一些简单的函数求值,比方,它知道函数min(20,23)的值是20 ,add(10,98) 的值是108等等.经过训练,Dr.Kong设计的机器人卡多甚至会计算一种嵌套的更复杂的表达式. 如果表达式能够简单定义为: 1. 一个正的十进制数 x 是一个表达式. 2. 假设 x 和 y 是 表达式,则 函数min(x,y )也是表达式,其值为x

数据结构算法C语言实现(八)--- 3.2栈的应用举例:迷宫求解与表达式求值

一.简介 迷宫求解:类似图的DFS.具体的算法思路可以参考书上的50.51页,不过书上只说了粗略的算法,实现起来还是有很多细节需要注意.大多数只是给了个抽象的名字,甚至参数类型,返回值也没说的很清楚,所以很多需要自己揣摩.这也体现了算法和程序设计语言的特点,算法更侧重本质的描述,而任何编程语言都要照顾到实现的细节以及数据类型等语法方面的需求. 表达式求值: [编码中....] 二.头文件 迷宫求解: 1 //3_2_maze.h 2 /** 3 author:zhaoyu 4 email:[em

四则运算表达式求值の各种心碎

实验三---四则运算表达式求值 一.基本要求: ( 1 ) 利用二叉树后序遍历来实现表达式的转换,同时可以使用实验三的结果来求解后缀表达式的值. ( 2) 输入输出格式: 输入格式:在字符界面上输入一个中缀表达式,回车表示结束. 请输入表达式: 输入一个中缀表达式 输出格式:如果该中缀表达式正确,那么在字符界面上输出其后缀表达式,其中后 缀表达式中两相邻操作数之间利用空格隔开:如果不正确,在字符界面上输出表达式错误提示. 逆波兰表达式为: 输出逆波兰表达式 运算结果为:输出运算后的结果 测试数据

lintcode 中等题:Evaluate Reverse Polish notation逆波兰表达式求值

题目 逆波兰表达式求值 在逆波兰表达法中,其有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达. 样例 ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"]

使用逆波兰式进行表达式求值

中缀表达式及后缀表达式图解中说明了使用逆波兰式进行表达式求值的方法,这里使用C++进行实现.实现和原理讲解有一点不同,需要进一步进行细化. 关于将中缀表达式转换成后后缀表达式的规则: 规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分:若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,一直到最终输出后缀表达式为止. 上面的规则转换成下面的执行规则: 1.遇到操作数:直接输出(添加到后缀