前缀后缀表达式

本文介绍了中缀表达式、前缀表达式(波兰表达式)和后缀表达式(逆波兰表达式),包括它们的计算规则和转换方法。前缀表达式和后缀表达式没有括号,运算符优先级明确,适合通过递归或栈求值。中缀表达式转后缀表达式和求值过程中,遵循特定的规则,例如依据运算符优先级和括号处理。
摘要由CSDN通过智能技术生成

引子:中缀表达式

我们把平时所用的标准四则运算表达式,即"3 + 4 × 5”叫做中缀表达式

中缀表达式的运算规则我们很熟悉了,计算顺序由运算符的优先级和括号来确定,常见的运算符优先级如下;

1、 括号具有最高优先级,可以用于改变默认的运算顺序。

2、 指数运算符(如乘方)具有较高优先级。

3、 乘法和除法具有比加法和减法更高的优先级,但是他们的结合性是从左到右。

4、 加法和减法具有最低优先级,也是从左到右结合的。

对于中缀表达式的计算规则也很简单:

1、 遍历表达式并将操作数和运算符按照顺序存储

2、 根据括号的优先级和结合性规则,进行括号内的计算

3、 依次按照运算符的优先级和结合性规则,计算乘法,除法,加法和减法的结果,知道表达式被完全求解为止

例:3 + 4 × 5

我们根据运算符优先级先计算4 × 5为20,再把3和20想加得到23

我们从小就接触中缀表达式,虽然已经很为得心应手,但难免有时会因为疏忽了运算符优先级而出错,而在计算机中直接求解中缀表达式显然是很困难的,所以20世纪50年代,波兰逻辑学家Jan Lukasiewicz创造性地提出了波兰表示,表达式的前缀和后缀表示。

前缀表达式(波兰表达式)

前缀表达式又称波兰表达式(Polish Notation ,PN),是一种将运算符置于操作数之前的表达式表示方法,以波兰数学家Jan Lukasiewicz的名字命名。

一般形式:运算符、操作数、操作数.......

遍历顺序:从右往左

例:+ 3 × 4 5 (对应中缀表达式 3 + 4 × 5)

我们从右往左去遍历,遇到操作数5,继续往左,遇到操作数4,继续往左,遇到运算符×,那么将前面得到的4、5作为*的操作数得到4 × 5=20,20是我们新的操作数,然后继续向左遍历,遇到操作数3,继而遇到运算符+,将20和3作为运算符+的操作数得到20 + 3 = 23,这就是我们最终的结果,与我们中缀表达式3 + 4 × 5的结果相同

那么在我们计算机中该如何去实现前缀(波兰)表达式的计算呢?

假如我们给定前缀(波兰)表达式

计算过程如下:

1、 从右往左遍历表达式,遇到操作数就压入栈中

2、 遇到运算符就从栈中取出两个操作数计算出新的操作数,再压入栈中

3、 表达式遍历结束,最终栈中剩余的一个操作数就是我们前缀表达式的结果

<

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
前缀表达式和后缀表达式都是一种不含括号的数学表达式,它们可以通过二叉树来表示,这种二叉树就是前缀/后缀表达式二叉树。 前缀表达式二叉树的构建方法是从右往左扫描前缀表达式,将操作数和操作符依次入栈,遇到操作符时从栈中弹出两个操作数作为该操作符的左右子节点,并将新的表达式入栈,直到扫描完整个前缀表达式。 后缀表达式二叉树的构建方法与前缀表达式二叉树类似,只不过是从左往右扫描后缀表达式。 以下是一个实现前缀表达式二叉树的C++代码示例: ```c++ #include <iostream> #include <stack> #include <string> using namespace std; // 定义二叉树结构体 struct TreeNode { char val; TreeNode* left; TreeNode* right; TreeNode(char c) : val(c), left(nullptr), right(nullptr) {} }; // 构建前缀表达式二叉树 TreeNode* buildTree(string& s) { stack<TreeNode*> stk; for (int i = s.size() - 1; i >= 0; i--) { char c = s[i]; if (isdigit(c)) { // 操作数入栈 stk.push(new TreeNode(c)); } else { // 操作符出栈,构建新的表达式节点 TreeNode* node = new TreeNode(c); node->left = stk.top(); stk.pop(); node->right = stk.top(); stk.pop(); stk.push(node); } } return stk.top(); } // 前序遍历输出二叉树 void preOrder(TreeNode* root) { if (root == nullptr) return; cout << root->val << " "; preOrder(root->left); preOrder(root->right); } int main() { string s = "+*1234"; TreeNode* root = buildTree(s); preOrder(root); // 输出:+ * 1 2 3 4 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EQUINOX1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值