中缀表达式转后缀表达式(C++)

100 阅读3分钟

中缀表达式转后缀表达式_牛客题霸_牛客网 (nowcoder.com)

整体思路:

  1. 遇到数字,直接输出
  2. 遇到符号
  1. 栈为空,符号直接入栈

  2. 如果是(,直接入栈

  3. 用当前符号和栈顶符号比较优先级

    当前符号>栈顶符号,符号直接入栈, 结束

    当前符号<=栈顶符号, 栈顶符号出栈输入,继续比较

    需要考虑:1:把栈符号都出完了 ,则栈空直接入栈 2:遇到),要一直出栈,直到遇见(为止

举例

输入2 + (4+6)/2 + 6/3

输出2 4 6 + 2 /

整体过程如下:

首先定义一个符号栈,和res

  1. 遇到数字2,直接输出, 此时栈为空, res为[2]
  2. 遇到+, 栈为空直接入栈, 栈为[+], res为[2]
  3. 遇到( 直接入栈, 栈为[+ (], res为[2]
  4. 遇到数字4直接输出 , 栈为[ + ( ], res为[ 2 4 ]
  5. 遇到+, 优先级低于栈顶元素,直接入栈,栈为[ + ( + ], res为[ 2 4 ]
  6. 遇到数字6, 直接输出, 栈为[ + ( + ], res为[ 2 4 6 ]

image-20241013113758874.png

7. 遇到) 一直出栈,直到遇到( , 栈为[ + ], res为[ 2 4 6 +]

image-20241013113948209

8. 遇到/ 比+优先级高,直接入栈

image-20241013114027141转存失败,建议直接上传图片文件
  1. 遇到数字2,直接输出
image-20241013114128824转存失败,建议直接上传图片文件
  1. 遇到+,优先级低于栈顶的/, 所以/出栈输出, 然后继续与栈顶+比较,优先级相同,我们是从左往右计算的,所以先出栈,再说 image-20241013114413331转存失败,建议直接上传图片文件

  2. 此时栈空了,把+入栈

  3. 然后遇到数字6 直接输出

  4. 然后遇到/,优先级大于栈顶符号,所以入栈

  5. 然后遇到数字3,直接输出

image-20241013114647268转存失败,建议直接上传图片文件
  1. 最后出栈输出
image-20241013114737953转存失败,建议直接上传图片文件

代码实践

#include <iostream>
#include <string>
#include <stack>
using namespace std;

// 比较符号优先级的
bool Priority(char ch, char topch) {
    if ((ch == '*' || ch == '/') && (topch == '+' || topch == '-'))
        return true;
    if (topch == '(' && ch != ')')
        return true;
    return false;
}

// 中缀表达式 => 后缀表达式
string MiddleToEndExpr(string expr) {
    string result;
    stack<char> s;

    for (char ch : expr) {
        if (ch >= 'a' && ch <= 'z') {
            result.push_back(ch);
        } else {
            for (;;) {
                // 处理符号了
                if (s.empty() || ch == '(') {
                    s.push(ch);
                    break;
                }

                // 比较当前符号ch和栈顶符号top的优先级
                char topch = s.top();
                // Priority:true ch > topch   false ch <= topch
                if (Priority(ch, topch)) {
                    s.push(ch);
                    break;
                } else {
                    s.pop();
                    if (topch == '(') // 如果遇见),一直出栈,直到(
                        break;
                    result.push_back(topch);
                }
            }
        }
    }

    // 如果符号栈还存留符号,直接输出到后缀表达式里面     + /
    while (!s.empty()) {
        result.push_back(s.top());
        s.pop();
    }

    return result;
}

int main() {
    std::string str;
    cin >> str;
    std::cout << MiddleToEndExpr(str) << std::endl;
}
// 64 位输出请用 printf("%lld")

备注

将数字全部用小写字母来代替了,如果是数字则不能用一个字符串来表示输入了,应该用字符串数组,这时输入应该改为

string input;
getline(cin, input); // 得到一行带空格的字符串

分割字符串

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string str = "one two three four";
    std::stringstream ss(str);
    vector<string>res;
    std::string word;
    while (ss >> word) {
        res.push_back(word);
    }
    return 0;
}