zoukankan      html  css  js  c++  java
  • 模板

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

    #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;
    }
    
  • 相关阅读:
    Spring ApplicationListener 理解
    Tomcat 的context.xml说明、Context标签讲解
    IntrospectorCleanupListener作用
    Dubbo 和 Spring Cloud微服务架构 比较及相关差异
    ZooKeeper原理 --------这可能是把ZooKeeper概念讲的最清楚的一篇文章
    Dubbo 入门
    makefile的调试器remake
    linux下的nmap工具能干什么?
    makefile中的patsubst函数有何作用?
    openwrt为何需要refresh新增的补丁?
  • 原文地址:https://www.cnblogs.com/Yinku/p/10736054.html
Copyright © 2011-2022 走看看