数据结构C++版 王红梅 OJ习题

1018: 表达式求值

Description

要求输入一个以字符串方式存储的表达式,利用栈,能够计算表达式的值。表达式中允许的运算符为+,-,*,/,%,(,)。

函数原型: int CalValue(char *s); s存储表达式,函数返回值为表达式的值,表达式中的操作数为正整数。

输入: 15+(3-5)*7

输出:1

Input

Output

Sample Input

5+7*(25-12)/2-3

Sample Output

47
//
// Created by Legends丶Hu on 2020/2/4.
//

#include <iostream>
#include <cstring>
#include <cctype>
//#include "Stack.h"

using namespace std;
const int StackSize = 100;

template<class T>
class Stack {
private:
    int top;
    T data[StackSize];
public:
    Stack();

    void Push(T x);

    T Pop();

    T GetTop();

    int Empty();

    ~Stack() {}
};

template<class T>
void Stack<T>::Push(T x) {
    if (top == StackSize - 1) throw "Overflow";
    data[++top] = x;
}

template<class T>
Stack<T>::Stack() {
    top = -1;
}

template<class T>
T Stack<T>::Pop() {
    if (Empty()) throw "Downflow";
    return data[top--];
}

template<class T>
T Stack<T>::GetTop() {
    return Empty() ? throw "Downflow" : data[top];
}

template<class T>
int Stack<T>::Empty() {
    return top == -1;
}

//3*(4+2)/2-5
int compare(char c) {//优先级比较
    switch (c) {
        case '#':
            return 0;
        case '(':
            return 1;
        case '+':
        case '-':
            return 2;
        case '*':
        case '/':
        case '%':
            return 3;
    }
}

int compute(int a, int b, char ch) {
    int res;
    switch (ch) {
        case '+':
            res = a + b;
            break;
        case '-':
            res = a - b;
            break;
        case '/':
            res = a / b;
            break;
        case '*':
            res = a * b;
            break;
        case '%':
            res = a % b;
            break;
    }
    return res;
}

int MidCalValue(char *s) {
    Stack<int> OPND;//操作数
    Stack<char> OPTR;//操作符
    OPTR.Push('#');
    for (int i = 0; i < strlen(s);) {
        if (isdigit(s[i])) {
            int num = 0;
            while (isdigit(s[i])) {
                num = num * 10 + s[i] - '0';
                i++;
            }
            OPND.Push(num);
        } else {
            //字符
            if (s[i] == '(')OPTR.Push(s[i]);
            else if (s[i] == ')') {
                char ch = OPTR.Pop();
                while (ch != '(') {
                    int a = OPND.Pop();
                    int b = OPND.Pop();
                    int x = compute(b,a,ch);
                    OPND.Push(x);
                    ch = OPTR.Pop();
                }
            } else {
                char ch = OPTR.GetTop();
                while (compare(ch) >= compare(s[i])) {
                    int a = OPND.Pop();
                    int b = OPND.Pop();
                    int x = compute(b,a,ch);
                    OPND.Push(x);
                    OPTR.Pop();
                    ch = OPTR.GetTop();
                }

                OPTR.Push(s[i]);
            }
            i++;
        }
    }
    char ch;
    while ((ch = OPTR.Pop()) != '#') {
        int a = OPND.Pop();
        int b = OPND.Pop();
        int x = compute(b,a,ch);
        OPND.Push(x);
    }
    return OPND.Pop();
}

void  ConvertPost(char *str,char *res) {
    Stack<char> s;
//    str[strlen(str)] = '#';
    s.Push('#');
    int index = 0;
    for (int i = 0; i < strlen(str);) {
        if (isdigit(str[i])) {
            while (isdigit(str[i])) {
                res[index++] = str[i++];
            }
            res[index++]=' ';
        } else {
            if (str[i] == '(') {
                s.Push(str[i]);

            } else if (str[i] == ')') {
                char ch = s.GetTop();
                while (ch != '(') {
                    res[index++] = ch;
                    res[index++] = ' ';
                    s.Pop();
                    ch = s.GetTop();
                }
                s.Pop();
            } else {
                char ch = s.GetTop();
                while (compare(ch) >= compare(str[i])) {
                    res[index++] = ch;
                    res[index++] = ' ';
                    s.Pop();
                    ch = s.GetTop();
                }
                s.Push(str[i]);
            }
            i++;
        }
    }
    char ch = s.GetTop();
    while ((ch = s.Pop()) != '#') {
        res[index++] = ch;
        res[index++] = ' ';
    }
    res[index] = '\0';
}

int PostCalValue(char *s) {
    Stack<int> stack;
    for(int i = 0; i < strlen(s); i++) {
        if(isdigit(s[i])) {
            int num = 0;
            while (isdigit(s[i])) {
                num = num * 10 + s[i] - '0';
                i++;
            }
            stack.Push(num);
            continue;
        } else if(s[i] != ' '){
            int a = stack.Pop();
            int b = stack.Pop();
            int x = compute(b,a,s[i]);
            stack.Push(x);
        }
    }
    return stack.Pop();
}

//3*(4+2)/2-5
//1 2 + 3 4 - *
//(1+1)*(3-4)
//5+7*(25-12)/2-3%3
int main() {
    char str[100],s[100];
    cin >> str;//
    ConvertPost(str,s);
    cout << MidCalValue(str) << endl;
/*    cout << s << endl;
    cout << PostCalValue(s) << endl;*/
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值