Vj数据结构实验6

注意

因为精度问题,请使用double存数据。

要求

  1. 创建栈类,采用数组描述;
  2. 计算数学表达式的值。
    输入数学表达式,输出表达式的计算结果。数学表达式由单个数字和运算符+-*/(构成,例如 2+3*(4+5)-6/4。假定表达式输入格式合法。

格式

输入

第一行一个整数n(1<=n<=100),代表表达式的个数。
接下来n行,每行一个表达式,保证表达式内的数字为单个整数,表达式内各运算符和数字间没有空格,且表达式的长度不超过2000。

输出

每行表达式输出一个浮点数,要求保留两位小数,保证输入表达式合法。

样例

输入

3
1+6/1*7+2*1*4+9/1+2*0*9+9+7/(9*5)-1*6-0*8-7-9*2+6-(0-5-2*8-7-9*5*(6-5*5*2*6-2-7-5+6*7+6*9-1*0*0+3*0+2/1-6/6+5))
0-4-1/6*(1-(6/7)-4+6+2+6*1)-1*7+2-8*2+0-(4+6-6*1+(3-8*6/4-6-5)*6/4/8+7-1*4/9*5)-0/6+1-0-2+7-2+6*4-3*6+2/8+6+1*6*2
5-3*9+5/1*5-9+1*8-6-8-4*1+5-2+9/3*2-2/5/(2-6)*2/7-9*0-2+4/6*6*7*8-8-8*6+8*9*(3+0*1/5/2*7*8+0-8*8-5+8/5*2-0)

输出

-9197.84
-3.47
-4362.57

限制

1s, 65536KiB for each test case.

#include <iostream>
#include <iomanip>
using namespace std;

template<class T>
class arraystack{
    public:
        arraystack(int inicialCapacity = 10);
        ~arraystack(){delete [] stack;}
        bool empty()const{return stackTop == -1;}
        int size()const{return stackTop + 1;}
        T & top(){return stack[stackTop];}
        void pop(){stack[stackTop--].~T();} // 删除栈顶
        void push(const T& theElement); // 压入栈
        // 改变长度
        void change(T* &a, int oldLength, int newLength){
            T* temp = new T[newLength]; // 新数组
            int number = min(oldLength, newLength); // 需要复制的个数
            copy(a, a + number, temp);
            delete []a; // 释放老数组的内存空间
            a = temp;
        }
        void kk(arraystack<double> &a, arraystack<char> &b); // 单步运算
        void output(string x);//输出
    private:
        int stackTop; // 当前栈顶
        int arrayLength; // 栈容量
        T *stack; // 元素数组
};

// 构造函数
template<class T>
arraystack<T>::arraystack(int inicialCapacity){
    arrayLength = inicialCapacity;
    stack = new T[arrayLength];
    stackTop = -1;
}

// 将元素压入栈
template<class T>
void arraystack<T>::push(const T& theElement){
    if(stackTop == arrayLength - 1){
        change(stack, arrayLength, arrayLength * 2);
        arrayLength *= 2;
    }
    // 在栈顶插入元素
    stack[++stackTop] = theElement;
}

// 符号的运算
template<class T>
void arraystack<T>::kk(arraystack<double> &a, arraystack<char> &b){
    if(b.top() == '('){
        return;
    }
    double x, y;
    x = a.top();
    a.pop();
    y = a.top();
    a.pop();
    switch(b.top()){
        case '+': x = x + y;
            break;
        case '-': x = y - x;
            break;
        case '*': x = x * y;
            break;
        case '/': x = y / x;
            break;
    }
    a.push(x);
    b.pop();
}

template<class T>
void arraystack<T>::output(string x){
    arraystack<double> a(x.size()); // a数字栈
    arraystack<char> b(x.size()); // b符号栈
    for(int i = 0; i < x.size(); i++){
        if(x[i] >= '0' && x[i] <= '9'){ // 数字直接压入栈
            a.push(x[i] - '0');
        }
        else{
            if(x[i] == '('){  // (直接压入
                b.push(x[i]);
            }
            else if(x[i] == ')'){
                while(b.top() != '('){ // 计算括号中的内容
                    kk(a, b);
                }
                b.pop(); // 删除(
            }
            else if(x[i] == '+' || x[i] == '-'){ // 加减的优先级最低,只要之前有运算符号(除())都要先计算
                if(b.top() == '(' || b.empty()){
                    b.push(x[i]);
                }
                else{
                    kk(a, b);
                    if(!b.empty() && b.top() != '('){
                        kk(a, b);
                    }
                    b.push(x[i]);
                }
            }
            else if(x[i] == '*' || x[i] == '/'){
                if(b.empty() || b.top() == '('){
                    b.push(x[i]);
                }
                else{
                    if(b.top() == '+' || b.top() == '-'){ // 乘除之前是加减的话,直接压入(优先级高于加减)
                        b.push(x[i]);
                    }
                    else if(b.top() == '*' || b.top() == '/'){ // 同优先级的先运算之前的
                        kk(a, b);
                        b.push(x[i]);
                    }
                }
            }
        }
    }
    while(!b.empty()){ // 将剩余未计算的进行计算
        kk(a, b);
    }
    // 输出最后计算得到的值
    cout << setprecision(2) << fixed << a.top() << endl; 
}
int main(){
    int N;
    arraystack<double> a;
    cin >> N;
    for(int i =0; i < N; i++){
        string ss;
        cin >> ss;
        a.output(ss);
    }
    
    return 0;
}

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值