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

一、概念

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

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


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;
}
四运算结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/563779.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CST电磁仿真软件波导端口和离散端口的设置流程【教程解读】

置波导端口 通过波导端口馈电! Simulation > Sources and Loads > Waveguide Port 假设Waveguide Port是无限长的波导上给定的Mode&#xff0c;用来激励电磁场。相比离散端口(Discrete Port)&#xff0c;波导端口可以提供很好的模式匹配&#xff0c;因此能提供更高的精…

Android Material Design学习笔记

Material Design控件学习记录 Toolbar 新建一个工程后&#xff0c;在res/values/themes.xml文件里 <resources xmlns:tools"http://schemas.android.com/tools"><!-- Base application theme. --><style name"Theme.MaterialTest" paren…

Python的round与Excel的round不一样?

Python四舍五入怎么做 round()奇进偶舍round函数既不是“四舍五入”的原则&#xff0c;也不是“四舍六入无成双”的原则。 decimal round() 偶然发现python的round函数和excel的round函数对某些数据的处理结果不一致。有看到博主提到是奇进偶舍的方法&#xff0c;但经过验证和…

深度学习与神经网络入门

前言 人工智能&#xff08;AI&#xff09;与机器学习&#xff08;ML&#xff09;与深度学习&#xff08;DL&#xff09;的关系&#xff1a; DL包含于ML&#xff0c;ML包含于AI。 即深度学习是机器学习一部分&#xff0c;机器学习又是人工智能的一个分支。 那么深度学习到底有…

关系型数据库的相关概念

表、记录、字段 表 一个实体集相当于一个表记录 一个实体相当于一个记录&#xff0c;在表中表表现为一行数据字段 一个字段相当于数据库表中的列 表的关联关系 一对一(一对一的表可以合并成一张表)一对多多对多 必须创建第三张表&#xff0c;该表通常称为联接表&#xff0c…

协议的定制之序列化与反序列化 | 守护进程

目录 一、再谈协议 二、序列化与反序列化 三、网络计算器的简单实现 四、网络计算器完整代码 五、代码改进 六、守护进程 七、Json序列化与反序列化 八、netstat 一、再谈协议 是对数据格式和计算机之间交换数据时必须遵守的规则的正式描述。简单的说了&#xff0c;网络…

java多线程-练习

需求 代码 使用Callable 方便返回执行的结果&#xff1a;每个线程的发送礼物的数量礼物清单&#xff1a;共享资源&#xff0c;方便上锁礼物数量&#xff1a;线程变量&#xff0c;每个线程发送礼物的数量 public class SendGiftThread implements Callable<Integer> {// 共…

通过命令行构建Django应用程序

假设读者安装好Django开发环境后&#xff08;这个环境搭建很容易&#xff0c;大家可以参看随意一个网文&#xff09;&#xff0c;就可以通过命令行构建Django应用程序了。通过命令行构建Django应用程序的关键&#xff0c;是使用一个Django框架自带的管理工具——django-admin.p…

springboot3 集成knife4j

knife4j介绍 Knife4j是一个集Swagger2 和 OpenAPI3为一体的增强解决方案。 springdoc地址&#xff1a;OpenAPI 3 Library for spring-boot Knife4j官网地址&#xff1a;Knife4j 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j 环境介绍 java&#xff1a;17 Spring…

你们项目日志是如何处理的???

ELK日志采集系统 1.什么是ELK ELK 是一套流行的数据搜索、分析和可视化解决方案&#xff0c;由三个开源项目组成&#xff0c;每个项目的首字母合起来形成了“ELK”这一术语&#xff1a; Elasticsearch (ES): Elasticsearch 是一个基于 Apache Lucene 构建的分布式、实时搜索与…

项目开发流程

项目开发流程 &#x1f469;‍&#x1f9b3;项目立项 估计项目的花费&#xff0c;确定大致的所需开发人员数&#xff0c;确定项目是否可行&#xff1b; &#x1f469;‍&#x1f9b0;需求分析 整体过程&#xff1a; 项目背景和目标&#xff0c;即项目的目的是什么 用户需求&…

动态Web项目讲解+Demo

web流程演示 请求路径 请求路径明确要请求的是哪个servlet 请求方式 servlet含有两种请求方式&#xff1a;doGet和doPost doGet&doPost 返回数据就是httpResponse&#xff0c;返回给success 参数 包含在request当中 成功 上述流程任何一步都没出问题&#xff0c;就会…

设计模式之创建型模式---工厂模式

文章目录 工厂模式概述简单工厂简单工厂的代码实现简单工厂的使用简单工厂应用场景 工厂方法工厂方法模式的代码实现工厂方法的使用工厂方法应用场景 抽象工厂抽象工厂模式代码实现抽象工厂的使用方法抽象工厂模式的应用场景 总结 工厂模式概述 工厂模式从名字就能看出&#x…

在【laravel框架】学习中遇到的常见的问题以及解决方法

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

.net core webapi 高颜值的接口管理系统界面取代swagger,更好调试和查看

.net core webapi 高颜值的接口管理系统界面取代swagger&#xff0c;更好调试和查看 安装 dotnet add package IGeekFan.AspNetCore.Knife4jUI --version 0.0.16配置文档&#xff1a; 配置起始页 builder.Services.AddSwaggerGen(c > {// 配置 Swagger 文档相关信息c.Swa…

开源项目实现简单实用的股票回测

1 引言 之前&#xff0c;尝试做股票工具一直想做的大而全&#xff0c;试图抓取长期的各个维度数据&#xff0c;然后统计或者训练模型。想把每个细节做到完美&#xff0c;结果却陷入了细节之中&#xff0c;最后烂尾了。 最近&#xff0c;听到大家分享了一些关于深度学习、时序…

【面试题】MySQL 事务的四大特性说一下?

事务是一个或多个 SQL 语句组成的一个执行单元&#xff0c;这些 SQL 语句要么全部执行成功&#xff0c;要么全部不执行&#xff0c;不会出现部分执行的情况。事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;由一个有限的数据库操作序列构成。 事务的主要作用是保证数…

Core dump(核心转储)

文章目录 core dump core dump 进程退出时有三种情况正常退出&#xff0c;退出结果不对&#xff0c;异常退出 低7位表示收到信号退出&#xff0c;次低八位代表进程正常退出它的退出码&#xff01;在第八位有一个core dump标志位&#xff0c;这个标志位表示进程收到信号做的动…

Leetcode 28. 找出字符串中第一个匹配项的下标

心路历程&#xff1a; 两个字符串匹配的问题基本都可以用动态规划解决&#xff0c;递推关系就是依次匹配下去 注意的点&#xff1a; 1、注意边界条件是匹配串needle到头&#xff0c;但是haystack不一定需要到头 2、这道题按照从i开始的字符串而不是从i结束的进行DP建模 解法…

vue---计算属性

姓名案例 1.使用插值语法实现 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>姓名案例_插值语法实现</title><!-- 引入Vue --><script type"text/javascript" src"../js/vue.js"&g…