C/C++的中缀转后缀并求值的实现

简单的中缀转后缀并求值的C/C++实现

中缀转后缀

Description

输入一个中缀算术表达式S,S中的操作数为0到9,只含+,-和*,/运算,也可能含有括号(),运算符的计算顺序和实际四则运算的计算顺序相同. 请输出与S等价的后缀表达式,注意输出结果不要含有多余的括号或空格.

Input

输入有多组数据.

每组数据是一个中缀表达式S,S的长度不超过50. 输入的S保证合法,而且不包含多余的空格或制表符.

输入以#号结束.

Output

对于每个中缀表达式,输出转换后的后缀表达式,每个输出占一行.

Sample Input

1
1+2*3
(1-2)/3
#

Sample Output

1
123*+
12-3/

话不多说,直接贴代码,具体分析见上一篇博客

#include <iostream>
#include <stdlib.h>
#include <string>
#include <stack>

using namespace std;

bool isBetter(char a, char b) {
  if ((a == '*' || a == '/') && (b == '+' || b == '-')) return true;
  return false;
}

int main() {
  string input;
  while(1) {
    cin >> input;
    if (input[0] == '#') break; // 判断是否结束
    int l = input.size();
    stack<char> op;
    for (int i = 0; i <= l; i++) {
      if (i != l) { // 判断是否到达结尾
        // 如果是数字,则直接输出
        if (input[i] >= '0' && input[i] <= '9') {
          cout << input[i];
        } else {
          // 如果栈为空或者是左括号,直接入栈
          if (op.empty() || input[i] == '(') {
            op.push(input[i]);
          } else if (input[i] == ')'){
            // 如果时右括号,则将栈输出,直到遇到一个左括号
            while(!op.empty() && op.top() != '(') {
              cout << op.top();
              op.pop();
            }
            op.pop();// 将左括号弹出不输出
          } else {
            // 如果是运算符,则比较其与栈顶运算符的优先级
            while (!op.empty()) {
              if (isBetter(input[i], op.top())) { // 如果优先级高,则入栈
                break;
              } else { // 如果优先级低,则输出栈顶,将当前运算符入栈
                if (op.top() != '(') { // 确保栈顶不是左括号,左括号仅在读到右括号时处理
                  cout << op.top();
                  op.pop();
                } else {
                  break;
                }
              }
            }
            op.push(input[i]); // 将当前运算符入栈
          }
        }
      } else { // 将剩下的操作符输出
        while (!op.empty()) {
          cout << op.top();
          op.pop();
        }
      }
    }
    cout << endl;
  }
  return 0;
}

计算中缀表达式的值

本题目将上面的转换封装为函数,并做了适当的处理以将不同的运算数分开

Description

输入中缀算术表达式S,S中的操作数为非负整数,只含+,-和*,/运算,也可能含有括号(),运算符的计算顺序和实际四则运算的计算顺序相同. 输出表达式S的值. 注意除法运算只取整数部分,例如1/2=0.

Input

输入有多组数据.

每组数据是一个算术表达式S,S的长度不超过100. 输入的S保证合法,而且不包含多余的空格或制表符. S的操作数、中间结果和最终结果都不会超过int类型的范围,也不会出现除数为0的情况.

输入以#号结束.

Output

对于每个算术表达式S,输出S的值,每个输出占一行.

Sample Input

1
478+522
(478+522)*10
1/2-1
#

Sample Output

1
1000
10000
-1

#include <iostream>
#include <stack>

using namespace std;

bool isBetter(char a, char b);
string toPostifix(string input);
int calculate(int x, int y, char t_op);
int main() {
    string input, postfix;
    while (1) {
        // 运用后缀表达式,遇到数字是入栈,遇到运算符时,从栈中取出并弹出两个数进行运算,将其运算结果压入栈中
        cin >> input;
        if (input[0] == '#') break;
        postfix = toPostifix(input); // 转成后缀表达式,用.将数字和操作符间隔开
        int ll = postfix.size();
        int tmpNum = 0;
        int mark = 0; // 用来标记是否输出是单个数字的情况
        stack<int> num;
        for (int i = 0; i < ll; i++) {
            if (postfix[i] == '.') { // 如果读到. 则将读取到的数入栈
                if (tmpNum != 0) {
                    int x = tmpNum;
                    num.push(x);
                    tmpNum = 0;
                    mark = 1;
                }
            } else {
                // 如果遇到的是数字,则逐步将其转成int
                if (postfix[i] >= '0' && postfix[i] <= '9') {
                    tmpNum = tmpNum*10+postfix[i]-'0';
                    mark = 2;
                } else {
                    // 遇到数字后面没有.而是操作符的情况下,也要将数字提取出来入栈
                    if (mark == 2) {
                        int x = tmpNum;
                        num.push(x);
                        tmpNum = 0;
                        mark = 1;
                    }
                    // 遇到运算符,计算出新的值,然后入栈
                    int num1 = num.top();
                    num.pop();
                    int num2 = num.top();
                    num.pop();
                    int ans = calculate(num2, num1, postfix[i]);
                    num.push(ans);
                }
            }
        }
        if (mark == 2) {
            cout << tmpNum << endl;
        } else if (!num.empty()) {
            cout << num.top() << endl;
        }
    }
    return 0;
}

bool isBetter(char a, char b) {
    if ((a == '*' || a == '/') && (b == '+' || b == '-')) return true;
    return false;
}


int calculate(int x, int y, char t_op) {
    if (t_op == '+') return x+y;
    if (t_op == '-') return x-y;
    if (t_op == '*') return x*y;
    return x/y;
}
string toPostifix(string input) {
    string tmp = "";
    int l = input.size();
    stack<char> op;
    for (int i = 0; i <= l; i++) {
        if (i != l) { // 判断是否到达结尾
            // 如果是数字,则直接输出
            if (input[i] >= '0' && input[i] <= '9') {
                tmp += input[i];
            } else {
                tmp += '.';
                // 如果栈为空或者是左括号,直接入栈
                if (op.empty() || input[i] == '(') {
                    op.push(input[i]);
                } else if (input[i] == ')'){
                    // 如果时右括号,则将栈输出,直到遇到一个左括号
                    while(!op.empty() && op.top() != '(') {
                        tmp += op.top();
                        op.pop();
                    }
                    op.pop();// 将左括号弹出不输出
                } else {
                    // 如果是运算符,则比较其与栈顶运算符的优先级
                    if (isBetter(input[i], op.top())) { // 如果优先级高,则入栈
                        op.push(input[i]);
                    } else { // 如果优先级低,则输出栈顶,将当前运算符入栈
                        if (op.top() != '(') { // 确保栈顶不是左括号,左括号仅在读到右括号时处理
                            tmp += op.top();
                            op.pop();
                        }
                        op.push(input[i]); // 将当前运算符入栈
                    }
                }
            }
        } else { // 将剩下的操作符输出
            while (!op.empty()) {
                tmp += op.top();
                op.pop();
            }
        }
    }
    return tmp;
}
  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值