表达式树创建与计算(中缀表达式转逆波兰式)

题目描述

给定一串计算表达式

例如 (1+2*4-2)*3+4 * (2+4)/2

计算此表达式的值,并输出此表达式树的前序中序后序序列。

题解思路

首先,给定的表达式为正常逻辑的中缀表达式,我们需要将其转化为逆波兰式(后缀表达式),如下给出理由

例如 a*b-c

它的二叉树如下
在这里插入图片描述
前序序列为:- * a b c
中序序列为: a * b - c
后序序列为: a b * c -

对于前序序列,运算顺序应该为首先对离运算符最近的ab操作,ab前有乘号,将ab相乘,代替ab的位置,然后此时离运算符最近的为ab的结果与c,前方的操作符为-号则进行a*b-c操作。而此种运算顺序实际上不利于代码模拟。

相反,对于后序序列,则可以用栈轻松模拟,首先创建一个操作数栈,从左到右遍历。

  • 首先为a,压入操作数栈
  • 对b来说,压入操作数栈
  • 对*来说,取出操作数栈中栈顶元素和次栈顶元素b,a并将这两个元素pop操作。将b,a进行相乘后重新压入操作数栈
  • 对c来说,压入操作数栈
  • 对-来说,取出操作数栈中栈顶元素和次栈顶c和a*b,将这两个元素进行先相减操作,重新压入栈。(注意为次栈顶减栈顶)
  • 结束后栈中剩下的一个数则为表达式的值

因此我们想要计算表达式,可以先将其转化成逆波兰式(后缀表达式),就可以计算出值,而对于如何从中缀表达式转成后缀表达式,思路如下:

首先创建一个运算符栈,从左到右遍历,利用vector存储答案

  • 如果为操作数,直接压入vector
  • 如果为运算符
    • 如果此时运算符栈为空,直接压入运算符栈
    • 如果运算符为(,左括号的话,直接压入运算符栈
    • 如果此时运算符为),右括号的话,不断将运算符栈顶元素压入vector,直到匹配到(,左括号为止(注意:左右括号都不进入vector)
    • 如果此时运算符优先级大于栈顶元素,直接压入运算符栈
    • 如果运算符优先级小于等于栈顶元素,不断将运算符栈顶元素压入vector,直到栈空或者栈顶元素优先级小于此运算符,然后将此运算符压入运算符栈。

vector中即为后缀表达式。
对于正确性,可以自己写几个例子简单模拟一下。

解决了从中缀转后缀,就可以算出值,而对于通过后缀表达式建立二叉树,思路与后缀表达式计算一样。

思路如下:(从左到右遍历后缀表达式)
首先创建一个指针栈

  • 如果此时为操作数,创建指针指向此数,将指针压入栈
  • 如果此时为操作符,创建指针指向此操作符,再将栈顶指针和次栈顶指针拿出,将此操作符指针的左孩子指针指向原次栈顶指针,右孩子指针指向原栈顶指针。再将此操作符指针压入栈中。

结束后栈中剩下的指针即为此二叉树的根结点指针。

代码如下

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
#include <vector>
using namespace std;
const int N=100010;
typedef struct node
{
   
   
    char data[1000];
    struct node *lchild;
    struct node *rchild;
}node,*root;
string str,str1;
vector<string>res;
int ans=0;
int fun2(string a)//运算符优先级判断
{
   
   
    if(a[0]=='+'||a[0]=='-')return 0;
    if(a[0]=='*'||a[0]=='/')return 1;
    if(a[0]=='(')return -1;
}
bool cmp(string a,string b)
{
   
   
    int x=fun2(a),y=fun2(b);
    if(x<y)return 1;
    return 0;
}
void fun1()//中缀表达式转后缀表达式
{
   
   
    vector<string>v;
    string p="";
    for(int i=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值