模板 - 表达式

一位数中缀表达式转后缀表达式并求后缀表达式值

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

//比较lhs的优先级是否不高于rhs,rhs表示栈顶的符号
bool priority(const char &lhs, const char &rhs) {
    if (rhs == '(')//左括号在栈外优先级最高
        return false;
    if (lhs == '+' || lhs == '-')
        return true;
    if ((lhs == '*' || lhs == '/') && (rhs == '*' || rhs == '/'))
        return true;
    return false;
}
//将中缀表达式转换成后缀式(逆波兰表达式)
string exchange(const string &str) {
    vector<char> vec;
    string res;
    stack<char> st;//操作符栈
    for (int i = 0; i < str.size(); ++i) {
        if (isdigit(str[i])) { //如果是数字,直接输出到后序表达式中
            vec.push_back(str[i]);
        } else { //如果是符号,需要与栈顶的元素进行比较
            if (st.empty() || str[i] == '(')//小括号在栈外优先级最高,直接压栈
                st.push(str[i]);
            else {
                if (str[i] == ')') { //遇到右括号,则弹栈,直到遇到左括号,两者相互抵消
                    while (st.top() != '(') {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    st.pop();
                } else {
                    //遇到的是其他操作符
                    //优先级比栈顶元素低
                    while (!st.empty()&&priority(str[i], st.top())) {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    //优先级比栈顶元素高,压栈
                    st.push(str[i]);
                }
            }
        }
    }
    while (!st.empty()) { //如果堆栈不为空,则将其中的元素全部弹出
        vec.push_back(st.top());
        st.pop();
    }
    for (auto v : vec)
        res += v;
    return res;
}

//定义四则运算
int operate(int first, int second, char op) {
    int res = 0;
    switch (op) {
    case '+':
        res = first + second;
        break;
    case '-':
        res = first - second;
        break;
    case '*':
        res = first * second;
        break;
    case '/':
        res = first / second;
        break;
    default:
        break;
    }
    return res;
}

int calculate(string input) {
    stack<int> st;//操作数堆栈
    for (auto &s : input) {
        if (isdigit(s)) { //如果是数字就压栈
            st.push(s - '0');
        } else { //遇到字符就弹出两个操作数进行运算
            int a = st.top();
            st.pop();
            int b = st.top();
            st.pop();
            st.push(operate(b, a, s));
        }
    }
    return st.empty() ? 0 : st.top();//最后的结果为栈顶元素
}

int main() {
    string str = "1+(3*4*5)/5+(4-8)*5-2/2+4";
    cout << str << endl;
    cout << exchange(str) << endl;
    cout << calculate(exchange(str)) << endl;
    return 0;
}

多位数中缀表达式转后缀表达式并求后缀表达式值,注意int可能溢出,不能求负数!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

string prework(string s) {
    string res="";
    int n=s.length();
    bool curnum=0;
    for(int i=0; i<n; i++) {
        if(isdigit(s[i])) {
            curnum=1;
            res+=s[i];
        } else {
            if(curnum==0) {
                res+=s[i];
            } else {
                curnum=0;
                res+='#';
                res+=s[i];
            }
        }
    }

    if(curnum) {
        curnum=0;
        res+='#';
    }

    return res;
}

//比较lhs的优先级是否不高于rhs,rhs表示栈顶的符号
bool priority(const char &lhs, const char &rhs) {
    if (rhs == '(')//左括号在栈外优先级最高
        return false;
    if (lhs == '+' || lhs == '-')
        return true;
    if ((lhs == '*' || lhs == '/') && (rhs == '*' || rhs == '/'))
        return true;
    return false;
}
//将中缀表达式转换成后缀式(逆波兰表达式)
string exchange(const string &str) {
    vector<char> vec;
    string res;
    stack<char> st;//操作符栈
    for (int i = 0; i < str.size(); ++i) {
        if (isdigit(str[i])||str[i]=='#') { //如果是数字,直接输出到后序表达式中
            vec.push_back(str[i]);
        } else { //如果是符号,需要与栈顶的元素进行比较
            if (st.empty() || str[i] == '(')//小括号在栈外优先级最高,直接压栈
                st.push(str[i]);
            else {
                if (str[i] == ')') { //遇到右括号,则弹栈,直到遇到左括号,两者相互抵消
                    while (st.top() != '(') {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    st.pop();
                } else {
                    //遇到的是其他操作符
                    //优先级比栈顶元素低
                    while (!st.empty()&&priority(str[i], st.top())) {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    //优先级比栈顶元素高,压栈
                    st.push(str[i]);
                }
            }
        }
    }
    while (!st.empty()) { //如果堆栈不为空,则将其中的元素全部弹出
        vec.push_back(st.top());
        st.pop();
    }
    for (auto v : vec)
        res += v;
    return res;
}

//定义四则运算
int operate(int first, int second, char op) {
    int res = 0;
    switch (op) {
    case '+':
        res = first + second;
        break;
    case '-':
        res = first - second;
        break;
    case '*':
        res = first * second;
        break;
    case '/':
        res = first / second;
        break;
    default:
        break;
    }
    return res;
}

int calculate(string input) {
    stack<int> st;//操作数堆栈
    int cur=0;
    for (auto s : input) {
        if (isdigit(s)) { //如果是数字就压栈
            cur=cur*10+(s - '0');
        } else if(s=='#') {
            st.push(cur);
            cur=0;
        } else { //遇到运算符就弹出两个操作数进行运算
            int a = st.top();
            st.pop();
            int b = st.top();
            st.pop();
            int t=operate(b, a, s);
            st.push(t);
        }
    }
    return st.empty() ? 0 : st.top();//最后的结果为栈顶元素
}

int main() {
    string str = "((1+8)*5+158)";
    string tmp=prework(str);//添加‘#’号分离数字
    tmp=exchange(tmp);//转后缀表达式
    cout << calculate(tmp) << endl;//求值
    return 0;
}
posted @ 2019-04-19 15:07  韵意  阅读(130)  评论(0编辑  收藏  举报