Vijos数据结构基础C++实验整理(六)——计算表达式(栈的应用)

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

样例:
输入:
3
1+6/17+214+9/1+209+9+7/(95)-16-08-7-92+6-(0-5-28-7-95(6-5526-2-7-5+67+69-100+30+2/1-6/6+5))
0-4-1/6*(1-(6/7)-4+6+2+61)-17+2-82+0-(4+6-61+(3-86/4-6-5)6/4/8+7-14/95)-0/6+1-0-2+7-2+64-36+2/8+6+162
5-39+5/15-9+18-6-8-41+5-2+9/32-2/5/(2-6)2/7-90-2+4/6678-8-86+89*(3+01/5/278+0-88-5+8/5*2-0)
输出:
-9197.84
-3.47
-4362.57

代码实现

#include <iostream>
#include <iomanip>
#include <sstream>  
#include <typeinfo>

using namespace std;

template <class T>
class arrayStack
{
public:
    arrayStack(int initialCapacity = 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 oneStepCalculate(arrayStack<double>& a, arrayStack<char>& b);
    void operate(string s);

private:
    int stackTop;
    int stackLength;
    T* stack;
};

template <class T>
arrayStack<T>::arrayStack(int initialCapacity){
    stackLength = initialCapacity;
    stack = new T[stackLength];
    stackTop = -1;
}

template<class T>
void arrayStack<T>::push(const T& theElement){
    if (stackTop == stackLength - 1){
        T* temp = new T[2 * stackLength];
        int number = min(stackLength, 2 * stackLength);
        copy(stack, stack + number, temp);
        delete[] stack;
        stack = temp;
        stackLength *= 2;
    }
    stack[++stackTop] = theElement;
}

template <class T>
void arrayStack<T>::oneStepCalculate(arrayStack<double>& number, arrayStack<char>& signal){
    if (signal.top() == '(')
        return;
    double x, y;

    x = number.top();
    number.pop();
    y = number.top();
    number.pop();

    switch (signal.top()){
    case '+':
        number.push(x + y);
        break;
    case '-':
        number.push(y - x);
        break;
    case '*':
        number.push(x * y);
        break;
    case '/':
        number.push(y / x);
        break;
    default:
        break;
    }

    signal.pop();
}

template <class T>
void arrayStack<T>::operate(string s){
    int length = s.size();

    arrayStack<double> number(length);
    arrayStack<char> signal(length);
    for (int i = 0; i < length; i++)
    {
        if (s[i] >= '0' && s[i] <= '9'){
            double m ;
            stringstream ss;
            ss << s[i];
            ss >> m;
            number.push(m);
        }
        else{
            switch (s[i])
            {
            case '+': {
                if (signal.empty() || signal.top() == '(')
                    signal.push(s[i]);
                else {
                    oneStepCalculate(number, signal);
                    if (!signal.empty() && signal.top() != '(')
                        oneStepCalculate(number, signal);
                    signal.push(s[i]);
                }
                break; 
            }
            case '-': {
                if (signal.empty() || signal.top() == '(')
                    signal.push(s[i]);
                else {
                    oneStepCalculate(number, signal);
                    if (!signal.empty() && signal.top() != '(')
                        oneStepCalculate(number, signal);
                    signal.push(s[i]);
                }
                break; 
            }
            case '*': {
                if (signal.empty() || signal.top() == '(')
                    signal.push(s[i]);
                else if (signal.top() == '+' || signal.top() == '-')
                    signal.push(s[i]);
                else if (signal.top() == '*' || signal.top() == '/') {
                    oneStepCalculate(number, signal);
                    signal.push(s[i]);
                }
                break; 
            }
            case '/': {
                if (signal.empty() || signal.top() == '(')
                    signal.push(s[i]);
                else if (signal.top() == '+' || signal.top() == '-')
                    signal.push(s[i]);
                else if (signal.top() == '*' || signal.top() == '/') {
                    oneStepCalculate(number, signal);
                    signal.push(s[i]);
                }
                break; 
            }
            case '(':
                signal.push(s[i]);
                break;
            case ')': {
                while (signal.top() != '(') {
                    oneStepCalculate(number, signal);
                }
                signal.pop();
                break; 
            }
            default:
                break;
            }
        }
    }

    while (!signal.empty()) {
        oneStepCalculate(number, signal);
    }

    cout << setprecision(2) << fixed << number.top() << endl;
}

int main(){
    arrayStack<double> a;
    int m;

    cin >> m;

    for (int i = 0; i < m; i++)
    {
        string equation;
        cin >> equation;
        a.operate(equation);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值