表达式求值(后缀表达式)(数据结构)

ops/2025/3/28 7:38:53/

一、概念

算术表达式是由操作数(运算数)、运算符(操作符)、和界线符(括号)三部分组成,在计算机中进行算术表达式的计算是通过堆栈来实现的。

二后缀表达式的逻辑和实现方式(逆波兰表达式求值)


1.定义
如果每个操作符跟在它的两个操作数之后,而不是两个操作数之间,那么这个表达式就是后缀表达,又称为逆波兰表达式,如:3 5 + 7 * 1 -

2.后缀表达式计算机求值
1.与前缀表达式类似,只是顺序是从左至右:
2.从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,其中先出栈的是右操作数,后出栈的是左操作数,
3.用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;
4.重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果

3.例子
计算后缀表达式的值:1 2 3 + 4 × + 5 -
1)从左至右扫描,将1,2,3压入栈;
2)遇到+运算符,3和2弹出,计算2+3的值,得到5,将5压入栈;
3)遇到4,将4压入栈
4)遇到×运算符,弹出4和5,计算5×4的值,得到20,将20压入栈;
5)遇到+运算符,弹出20和1,计算1+20的值,得到21,将21压入栈;
6)遇到5,将5压入栈;
7)遇到-运算符,弹出5和21,计算21-5的值,得到16为最终结果

三代码实现:

#include<iostream>
using namespace std;
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAXSIZE 100
#define ok 1
#define error 0
#define ovrflow -1
typedef int status;
typedef struct number{// 数值 int data;struct number *next;
}number,*number1;
typedef struct signal{// 字符 char data;struct signal *next;
}sign,*sign1;
status push1(number1 &s,int elem);
status push2(sign1 &s,char elem);
status in(char elem);
int pop1(number1 &s);
int pop2(sign1 &s);
status gettop1(number1 s);
char gettop2(sign1 s);
int get_index(char str);
char precede(char a, char b);
int operate(int x,char a,int y);
char characters[7] = {'+', '-', '*', '/', '(', ')', '#'};
char priority[7][7] = {{'>', '>', '<', '<', '<', '>', '>'},{'>', '>', '<', '<', '<', '>', '>'},{'>', '>', '>', '>', '<', '>', '>'},{'>', '>', '>', '>', '<', '>', '>'},{'<', '<', '<', '<', '<', '=', ' '},{'>', '>', '>', '>', ' ', '>', '>'},{'<', '<', '<', '<', '<', ' ', '='}
}; // 各个运算符之间的优先级关系int get_index(char str)
{// 获取相应运算符的索引for(int i = 0; i < 7; i++){if(str==characters[i]) return i;}printf("未找到匹配的字符\n");
}char precede(char a, char b)
{ //获取两个运算符之间的优先级关系int x = get_index(a);int y = get_index(b);return priority[x][y];
}
int main(int argc, char** argv){while(1){number1 s1=NULL;sign1 s2=NULL;//初始化 int x,y,n,elem=0,flag=0,j,k=0;char *a=new char[100],c,m;while(1){cout<<"请输入表达式:";scanf("%s",a);x=strlen(a);push2(s2,'#');for(int i=0;i<x;i++){if(flag==1) break;if(a[i]!='#'||gettop2(s2)!='#')if(in(a[i])!=0){//如果是数值 k=0;k=k*10+(a[i]-48);i++;while(in(a[i])!=0){k=k*10+(a[i]-48);i++;}i--;push1(s1,k);}else {if(a[i]==' '){continue;}switch(precede(gettop2(s2),a[i])){case '<':push2(s2,a[i]);break;case '=':pop2(s2);break;case '>':c=pop2(s2);y=pop1(s1);n=pop1(s1);elem=operate(n,c,y);push1(s1,elem);i--;break;default:cout<<"该优先级不存在,表达式错误,请重新输入"<<endl;flag=1; }}} printf("%d\n",gettop1(s1));}}return 0;
}
status in(char c){if(c>=48&&c<=58){return ok;}return error;
}
status push1(number1 &s,int elem){number *p;p=new number;p->data=elem;p->next=s;s=p;return ok;
}
status push2(sign1 &s,char elem){sign *p;p=new sign;p->data=elem;p->next=s;s=p;return ok;
}
int pop1(number1 &s){int x;if(s==NULL) return error;number *p=s;s=s->next;x=p->data;delete p;return x;
}
int pop2(sign1 &s){char c;if(s==NULL) return error;sign *p=s;s=s->next;c=p->data;delete p;return c;
}
status gettop1(number1 s){if(s==NULL) return error;return s->data;
}
char gettop2(sign1 s){if(s==NULL) return error;return s->data;
}
int operate(int x,char a,int y){if(a=='+') return x+y;if(a=='-') return x-y;if(a=='*') return x*y;if(a=='/') return x/y;
}
四运算结果:


http://www.ppmy.cn/ops/15007.html

相关文章

Linux关闭swap分区操作[适用于CDH报警等]

1.查看swap分区挂载路径(没卵用) swapon -s 2.设置配置文件的swap配置 echo “vm.swappiness 0” > /etc/sysctl.conf 3.设置内存中的swap状态。有时候配置文件为0&#xff0c;但集群或服务仍然使用了swap分区&#xff0c;可能原因就是内存没有同步配置 echo “0” > …

13 JavaScript学习:运算符

JavaScript 运算符 JavaScript 中有多种类型的运算符&#xff0c;包括以下几类&#xff1a; 算术运算符&#xff1a;用于执行基本的数学运算&#xff0c;如加法&#xff08;&#xff09;、减法&#xff08;-&#xff09;、乘法&#xff08;*&#xff09;、除法&#xff08;/&a…

磨损对输送带安全的影响

磨损对输送带安全的影响 在工业生产中&#xff0c;输送带作为重要的物流传输设备&#xff0c;广泛应用于煤炭、化工、冶金、电力、建材等多个行业。然而&#xff0c;输送带在使用过程中不可避免地会出现磨损现象&#xff0c;这不仅会影响其使用寿命&#xff0c;还可能对生产安…

C++必修:从C到C++的过渡(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. 缺省参数 1.1. 缺省参数的使用 缺省参数是声明或定义函数时为函数的参数指定…

echarts树图-实现拓扑图效果

使用echarts树图来实现拓扑图效果&#xff0c;其效果如下&#xff1a; 代码如下&#xff1a; const data {name: XXX公司,children: [{name: 网络主机,children: [{name: 普通路由器,children: [{name: 智能网关},{name: 192.168.1.0/24}]}]},{name: 企业路由器},{name: 三…

【golang学习之旅】报错:a declared but not used

目录 报错原因解决方法参考 报错 代码很简单&#xff0c;如下所示。可以发现a和b都飙红了&#xff1a; 运行后就会出现报错&#xff1a; 报错翻译过来就是a已经声明但未使用。当时我很疑惑&#xff0c;在其他语言中从来没有这种情况。况且这里的b不是赋值了吗&#xff0c;怎…

全新Storm Core API管理系统源码 免授权版

全新Storm Core API管理系统源码 免授权版 本系统为API系统,实现了api集成等基础功能,以后可能会更新key调用api,或者实现付费功能,敬请期待,前端模板均无加密,用户可自行二开,具体请看图 测试环境:PHP7.2+MySQL5.6 访问:http://你的域名/install 进行安装 伪静态…

Centos 7.9 一键安装 Oracle 12CR2(240116)单机 PDB

前言 Oracle 一键安装脚本&#xff0c;演示 CentOS7.9 一键安装 Oracle 12CR2 单机PDB&#xff08;240116&#xff09;过程&#xff08;全程无需人工干预&#xff09;。&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地址&#xff1a;Shell脚…