前缀表达式,中缀表达式,后缀表达式转化和计算

本文介绍如何将中缀表达式转换为前缀和后缀表达式,并提供了具体的算法步骤及实例解析。此外还讨论了利用栈进行表达式求值的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前缀表达式,中缀表达式,后缀表达式转化和计算

1、定义

  前缀表达式(波兰表达式)就是不含括号的算术表达式,而且它是将运算符写在前面,操作数写在后面的表达式,也称为波兰表达式。例如,- 1 + 2 3,它等价于1-(2+3)。
  后缀表达式(逆波兰表达式)运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序
  中缀表达式就是我们日常使用的,如:(2 + 1) * 3 。
  注:运算符优先级

  低 -> 高

       + -     * / %

实际上如:+和-也有优先级,不过对运算结果(表达式可能不同)无影响,在此忽略了

2、中缀表达式转化为前缀表达式

  2.1 算法描述

  (1)首先构造一个运算符栈S1和一个储存中间结果的栈S2。
  (2)从右至左扫描中缀表达式
        (3)如果是操作数时,将其压入S2。
  (4)如果是运算符,则与S1栈顶元素比较优先级:

  •    如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
  •    否则,若该运算符优先级比栈顶运算符的较高或相等,也将运算符压入S1;
  •    否则,将S1栈顶的运算符弹出并压入到S2中,再与S1中新的栈顶运算符相比较

  (5)遇到括号时:

  •         如果是右括号“)”,则直接压入S1;
  •   如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号 丢弃;

  (6)重复步骤(2)至(5),直到表达式的最左边;
  (7)若表达式扫描完,将S1中剩余的运算符依次出栈并压入S2;
  (8)依次将S2中的元素出栈,结果即为对应的前缀表达式。

  2.2 将中缀表达式3+5*(2+6)-1转化为前缀表达式过程:


  最后依次将S2中的元素出栈得:-+3*5+261

  2.3 用前缀表达式的求值

  对于一个前缀表达式的求值而言,需要使用一个栈S
       (1)从右至左扫描表达式
       (2)如果是操作数,则将其入栈S1
       (3)如果是运算符,则将栈S出栈2次,将出栈的两个数作相应的运算(注意前后顺序,先出栈的在左边),然后把得到的结果入栈S。
       (4)一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。

       前缀表达式:-+3*5+261


3、中缀表达式转化为后缀表达式

  3.1 算法描述

  (1)首先构造一个运算符栈S1和一个储存中间结果的栈S2。
  (2)从左至右扫描中缀表达式
        (3)如果是操作数时,将其压入S2。
  (4)如果是运算符,则与S1栈顶元素比较优先级:

  •    如果S1为空,或栈顶运算符为右括号“(”,则直接将此运算符入栈;
  •    否则,若该运算符优先级比栈顶运算符的较高或相等,也将运算符压入S1;
  •    否则,将S1栈顶的运算符弹出并压入到S2中,再与S1中新的栈顶运算符相比较

  (5)遇到括号时:

  •         如果是左括号“(”,则直接压入S1;
  •   如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;

  (6)重复步骤(2)至(5),直到表达式的最右边;
  (7)若表达式扫描完,将S1中剩余的运算符依次出栈并压入S2;
  (8)从左往右依次读取S2中的元素,即为对应的后缀表达式。
  和转化前缀表达式的区别是最开始扫描和最后读取方向不同
  具体计算略

  2.3 用前缀表达式的求值

        同上。

另外其实还有一个更好的方法,适合笔算,不适合机器。
如:3+5*(2+6*4-8)-
根据实际先后计算顺序算
x=6*4=64*
x=2+x=264*+
x=x-8=264*+8-
x=3+x=3264*+8-+
x=x-1=3264*+8-+1-
其实这才是真正正确的,上面都是忽略了+和-,*和/ 的优先顺序的。

中缀表达式转换为三元式(也称为前缀逆波兰表示法)的过程是一种算法,主要用于简化表达式计算中缀表达式通常包含操作符操作数,例如 `A + B * C`。三元式则将运算符置于其操作数之后,如 `* + A B C`。 这个过程被称为解析树(Parse Tree)转换,步骤包括: 1. **创建一个空栈**:用于存储操作数。 2. **从左到右遍历中缀表达式**: - 如果遇到数字,将其压入栈。 - 如果遇到操作符: - 如果操作符优先级高于栈顶的操作符,那么将栈顶的元素弹出,直到找到一个优先级低于当前操作符的元素或者栈为空,然后将该操作符压入栈。 - 否则,直接将当前操作符压入栈。 3. **处理结束**:如果栈不为空,意味着还有剩余的操作数未处理,将它们依次弹出并添加到结果三元式末尾,用空格分隔。 以下是一个简单的C++示例,使用递归策略: ```cpp #include <stack> std::string infixToPostfix(const std::string& expr) { std::stack<char> opStack; std::string postfixExpr = ""; const char* precedence = "+-*/^"; // 定义操作符的优先级 for (char c : expr) { if (isdigit(c)) { // 数字直接添加到后缀表达式 postfixExpr += c; } else if (c == '(') { // 左括号进入栈 opStack.push(c); } else if (c == ')') { // 右括号,直到左括号被匹配才出来 while (!opStack.empty() && opStack.top() != '(') { postfixExpr += opStack.pop(); } if (opStack.top() != '(') { throw "Invalid expression"; } opStack.pop(); // 出栈左括号 } else { // 操作符 while (!opStack.empty() && precedence[opStack.top()] >= precedence[c]) { postfixExpr += opStack.pop(); } opStack.push(c); // 将操作符压入栈 } } // 处理完所有字符后,将栈中的操作符全部加入后缀表达式 while (!opStack.empty()) { postfixExpr += opStack.pop(); } return postfixExpr; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值