中缀表达式转后缀表达式与后缀表达式计算(详解)

**中缀表达式转后缀表达式的一般步骤如下:
1:创建一个空的栈和一个空的输出列表。
2:从左到右扫描中缀表达式的每个字符。
3:如果当前字符是操作数,则直接将其加入到输出列表中。
4:如果当前字符是运算符,比较其与栈顶运算符的优先级:

  1. a. 如果栈为空或栈顶运算符是左括号"(“,则直接将当前运算符入栈。
    b. 如果当前运算符的优先级高于栈顶运算符的优先级,则将当前运算符入栈。
    c. 如果当前运算符的优先级低于或等于栈顶运算符的优先级,则将栈顶运算符弹出并加入到输出 列表中,
    直到栈为空或栈顶运算符的优先级低于当前运算符的优先级,然后将当前运算符入栈。
    d. 如果当前字符是右括号”)“,则依次弹出栈中的运算符并加入到输出列表中,
    直到遇到左括号”("为止,此时将左括号出栈且不加入输出列表。

    5:扫描完整个中缀表达式后,将栈中剩余的运算符依次弹出并加入到输出列表中。
    6:输出列表即为转换后的后缀表达式。
    举个例子:
    中缀表达式:2 + 3 * (4 - 1)
    转换为后缀表达式:2 3 4 1 - * +
    具体实现需要根据编程语言和数据结构来进行操作。
    **
    在这里插入图片描述

项目结构
在这里插入图片描述项目头文件结构QueueStorage.h
在这里插入图片描述项目头文件代码

#ifndef LINKSTACK_H
#define LINKSTACK_H
#include <stdio.h>
#include <stdlib.h>
// 链式栈的节点
typedef struct LINKNODE {struct LINKNODE* next;
}LinkNode;
// 链式栈
typedef struct LINKSTACK {LinkNode head;int size;}LinkStack;// 初始化函数
LinkStack* Init_LinkStack();
// 入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data);
// 出栈
void Pop_LinkStack(LinkStack* stack);
// 返回栈顶元素
LinkNode* TopLinkStack(LinkStack* stack);
// 返回栈元素的个数
int Size_LinkStack(LinkStack* stack);
// 清空栈
void Clear_LinkStack(LinkStack* stack);
// 销毁栈
void FreeSpace_LinkStack(LinkStack* stack);
#endif

项目cpp文件QueueStorage.cpp
在这里插入图片描述项目cpp文件代码QueueStorage.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "QueueStorage.h"// 初始化函数
LinkStack* Init_LinkStack() {LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));stack->head.next = NULL;stack->size = 0;return stack;
};
// 入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data) {if (stack == NULL) {return;}if (data == NULL) {return;}// 入栈data->next = stack->head.next;stack->head.next = data;stack->size++;
};
// 出栈
void Pop_LinkStack(LinkStack* stack) {if (stack == NULL) {return;}if (stack->size == 0) {return;}// 第一个有效节点LinkNode* pNext = stack->head.next;stack->head.next = pNext->next;stack->size--;};
// 返回栈顶元素
LinkNode* TopLinkStack(LinkStack* stack) {if (stack == NULL) {return NULL;}if (stack->size == 0) {return NULL;}// 返回栈顶元素return stack->head.next;
};// 返回栈元素的个数
int Size_LinkStack(LinkStack* stack) {if (stack == NULL) {return -1;}return stack->size;
};
// 清空栈
void Clear_LinkStack(LinkStack* stack) {if (stack == NULL) {return;}// 清空栈stack->head.next = NULL;stack->size = 0;};
// 销毁栈
void FreeSpace_LinkStack(LinkStack* stack) {if (stack == NULL) {return;}free(stack);
};

项目主文件截图
在这里插入图片描述项目主文件代码main.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "QueueStorage.h"int IsNumber(char c) {return c >= '0' && c <= '9';
}
// 判断是不是左括号
int IsLeft(char c) {return c == '(';
}
// 判断是不是右括号
int IsRight(char c) {return c == ')';
}
// 判断是不是运算符号
int IsOperator(char c) {return c == '+' || c == '-' || c == '*' || c == '/';
}
//返回运算符号的优先级
int GetPriority(char c) {if (c == '*' || c == '/') {return 2;}if (c == '+' || c == '-') {return 1;}return 0;
}//使用企业链表的方式进行实现需要添加结构体
typedef struct MYCHAR {LinkNode node;char* p;}MyChar;// 对于数字的操作
void NumberOperate(char* p) {printf("%c", *p);
}
// 创建MyChar
MyChar* CreateMyChar(char* p) {MyChar* mychar = (MyChar*)malloc(sizeof(MyChar));mychar->p = p;return mychar;
}// 对于左括号的操作
void LeftOperate(LinkStack* stack,char* p) {Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));
}
// 对于右括号的操作
void RightOperate(LinkStack* stack) {// 判断栈中是否存在元素while (Size_LinkStack(stack) > 0) {// 将里面的元素取出MyChar* mychar = (MyChar*)TopLinkStack(stack);// 如果匹配到左括号的话就弹出if (IsLeft(*(mychar->p))) {Pop_LinkStack(stack);break;}// 输出printf("%c", *(mychar->p));// 弹出Pop_LinkStack(stack);// 释放内存free(mychar);}
}
// 运算符号的操作
void OperatorOperate(LinkStack* stack, char* p) {// 取出栈顶符号MyChar* mychar = (MyChar*)TopLinkStack(stack);if (mychar == NULL) {Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));return;}// 如果栈顶优先级低于符号的优先级直接入栈if (GetPriority(*(mychar->p) < GetPriority(*p))) {Push_LinkStack(stack,(LinkNode*)CreateMyChar(p));return;}else {// 如果栈顶符号优先级不低while (Size_LinkStack(stack) > 0) {MyChar* mychar2 = (MyChar*)TopLinkStack(stack);// 如果优先级低当前的符号入栈if (GetPriority(*(mychar2->p)) < GetPriority(*p)) {Push_LinkStack(stack, (LinkNode*)CreateMyChar(p));break;}// 输出printf("%c ", *(mychar2->p));// 弹出Pop_LinkStack(stack);// 释放free(mychar2);}}
}int main()
{/*栈的应用:中缀表达式转后缀表达式*/char* str = (char *)"8 + (3 - 1) * 5";// 遍历字符串char* p = str;// 创建栈LinkStack* stack = Init_LinkStack();while (*p != '\0') {// 判断是否数数字,如果是数字的话直接输出if (IsNumber(*p)) {NumberOperate(p);}// 判断是不是左括号,如果是左括号直接进栈if (IsLeft(*p)) {LeftOperate(stack,p);}// 如果是右括号的话将栈顶符号弹出知道匹配到左括号为止if (IsRight(*p)) {RightOperate(stack);}// 如果是运算符号的话if (IsOperator(*p)) {OperatorOperate(stack,p);}p++;}//将栈中剩余的元素弹出并输出while (Size_LinkStack(stack) > 0) {MyChar* mychar = (MyChar*)TopLinkStack(stack);printf("%c", *(mychar->p));Pop_LinkStack(stack);free(mychar);}system("pause");return 0;
}

修改运行界面
在这里插入图片描述在这里插入图片描述在这里插入图片描述项目运行结果

在这里插入图片描述
后缀表达式相关原理

在这里插入图片描述计算这个后缀表达式"2 3 4 1 - * +"。**

首先,我们从左到右扫描后缀表达式,遇到数字就将其入栈,遇到运算符则将栈顶的两个数字弹出进行计算,然后将结果入栈。
具体计算过程如下:

  1. 将2和3入栈
  2. 遇到4,入栈
  3. 遇到1,入栈
  4. 遇到减号"-",弹出栈顶两个数字1和4,计算4-1=3,将结果3入栈
  5. 遇到乘号"",弹出栈顶两个数字3和3,计算33=9,将结果9入栈
  6. 遇到加号"+",弹出栈顶两个数字9和2,计算9+2=11,将结果11入栈
  7. 后缀表达式扫描结束,栈顶的数字11即为最终的计算结果。

主文件
在这里插入图片描述
主文件截图
在这里插入图片描述主文件代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "QueueStorage.h"int IsNumber2(char c) {return c >= '0' && c <= '9';
}
typedef struct MYNUM{LinkNode node;int val;}MyNum;
int Calculate(int left,int right,char c) {int ret = 0;switch (c) {case '+':ret = left + right;break;case '-':ret = left - right;break;case '*':ret = left * right;break;case '/':ret = left / right;break;default:break;}return ret;
}int main(void) {/*根据后缀表达式求解*/char* str = (char *)"831-5*+";char* p = str;// 创建栈LinkStack* stack = Init_LinkStack();// 对后缀表达式进行扫描while (*p != '\0') {// 如果是数字直接入栈if (IsNumber2(*p)) {MyNum* num = (MyNum*)malloc(sizeof(MyNum));num->val = *p - '0';Push_LinkStack(stack,(LinkNode*)num);}else {MyNum* right = (MyNum*)TopLinkStack(stack);// 如果是运算符的话,先从栈中弹出右操作数int rightNum = right->val;Pop_LinkStack(stack);free(right);// 取出左操作数MyNum* left = (MyNum*)TopLinkStack(stack);int leftNum = left->val;Pop_LinkStack(stack);free(left);int ret = Calculate(leftNum, rightNum, *p);// 结果入栈MyNum* num = (MyNum*)malloc(sizeof(MyNum));num->val = ret;Push_LinkStack(stack, (LinkNode*)num);}p++;}if (Size_LinkStack(stack) == 1) {MyNum* num = (MyNum*)TopLinkStack(stack);printf("运算结果是%d\n", num->val);Pop_LinkStack(stack);free(num);}// 释放栈FreeSpace_LinkStack(stack);system("pause");return 0;
}

运行结果展示:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 常用命令汇总

1 linux定时任务 查看定时任务&#xff1a;crontab -l 每晚一点半执行定时任务&#xff1a; 30 1 * * * sh /var/lib/pgsql/pg_db_backup.sh >> /var/lib/pgsql/pg_db_backup.log 2>&1 配置定时任务&#xff1a;crontab -e 2 linux 内核版本查询 cat /etc/r…

我有才打造私域流量的知识付费小程序平台

在当今数字化时代&#xff0c;知识付费市场正在迅速崛起&#xff0c;而私域流量的概念也日益受到重视。私域流量指的是企业通过自有渠道获取的、能够自由支配的流量&#xff0c;这种流量具有更高的用户粘性和转化率。因此&#xff0c;打造一个基于私域流量的知识付费小程序平台…

实现:切换页面切换标题,扩展 vue-router 的类型

布局容器-页面标题 网址&#xff1a;https://router.vuejs.org/zh/guide/advanced/meta 给每一个路由添加 元信息 数据 router/index.ts const router createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{ path: /login, component: () > im…

第一启富金:新添澳大利亚(ASIC)牌照

第一启富金&#xff1a;澳大利亞證券及投資委員會&#xff08;ASIC&#xff09; GOLDWELL GLOBAL PTY LTD 是 WHOLESALE INVESTOR SERVICES PTY LTD&#xff08;CAR 編號 001304943&#xff09;的企業授權代表開發澳大利亞客戶&#xff0c;WHOLESALE INVESTOR SERVICES PTY LT…

XML是什么

XML是是什么&#xff1f; XML&#xff08;Extensible Markup Language&#xff09;&#xff0c;中文是可扩展标记语言&#xff0c;是标准通用标记语言的子集。它是一种标记语言&#xff0c;用于标记电子文档&#xff0c;使其结构化。 XML可以用来标记数据&#xff0c;定义数据…

【软件推荐】文本转语音,语音转wav,导入ue5

文字转语音 在线免费文字转语音 - TTSMaker官网 | 马克配音https://ttsmaker.cn/ 文件转换器 语音转wav Convertio — 文件转换器https://convertio.co/zh/

HarmonyOS应用程序框架——UIAbility实操

UIAbility概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互。UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面。 每一个UIAbility实例&#xff0c;都对应于一个最近任务列表中的任务。 一个应用可以有一个UIAbility&…

Leetcode—901.股票价格跨度【中等】

2023每日刷题&#xff08;五十二&#xff09; Leetcode—901.股票价格跨度 算法思想 实现代码 class StockSpanner { public:stack<pair<int, int>> st;int curday -1;StockSpanner() {st.emplace(-1, INT_MAX);}int next(int price) {while(price > st.top(…

油猴(Tampermonkey)浏览器插件简单自定义脚本开发

介绍 浏览器插件&#xff0c;包括油猴插件和其他插件&#xff0c;通过它们可以实现浏览器网页的定制化与功能增强。 其他插件一般只有某种具体的功能&#xff0c;且已经写死而不能更改&#xff0c;比如Adblock插件只用于去广告。 油猴插件是一款用于管理用户脚本的插件&…

使用Rust 构建C 组件

协议解析&#xff0c;这不就很快了&#xff0c;而且原生的标准库红黑树和avl 树支持&#xff0c;异步tokio 这些库&#xff0c;编写应用组件就很快了 rust 标准库不支持 unix 的消息队列&#xff0c;但是支持 shm 和 uds&#xff0c;后者从多方面考虑都比&#xff0c;消息队列更…

教育类直播介绍

教育类直播是一种在线教育形式&#xff0c;它允许学生和教师通过实时视频通话进行互动学习。这种学习方式可以为学生提供更灵活的学习时间和地点&#xff0c;同时也可以帮助教师更好地与学生进行互动和指导。 在教育类直播中&#xff0c;学生可以通过网络与教师和其他学生进行…

c/c++中一些不常用但有用的知识

1.变长数组 bool fun(int cnt) {unsigned char data[cnt];return true; } 在 C 语言中&#xff0c;变长数组&#xff08;Variable Length Arrays&#xff0c;VLA&#xff09;是 C99 标准引入的特性&#xff0c;允许使用变量来定义数组的长度。因此&#xff0c;在 C 版本的代码…

快速在VMware虚拟机上运行Kali Linux(保姆级教程)

本期将演示如何在VMware虚拟机上快速、轻松地安装Kali Linux。Kali Linux是一款专为渗透测试和网络安全而设计的操作系统&#xff0c;拥有很多强大的工具和功能。 在运行任何虚拟机之前&#xff0c;一定要先确保已经打开主板BIOS上的虚拟化支持。 下载VMware 接着来到vmware的…

vue 一直运行 /sockjs-node/info?及 /sockjs-node/info报错解决办法

sockjs-node介绍 sockjs-node 是一个JavaScript库&#xff0c;提供跨浏览器JavaScript的API&#xff0c;创建了一个低延迟、全双工的浏览器和web服务器之间通信通道。 服务端&#xff1a;sockjs-node&#xff08;https://github.com/sockjs/sockjs-node&#xff09; 客户端&a…

[全志Tina/Linux]全志修改bootlogo分区数据从而修改bootlogo

一、需求 在不进行镜像烧录的情况下&#xff0c;通过启动项或脚本将已存在于主板的bootlogo文件更新到bootlogo分区中&#xff0c;从而实现bootlogo的更新 二、操作 1、在主板上查找bootlogo文件路径 find -name bootlogo* 实机效果&#xff1a; 2、进入文件夹路径 cd ./d…

Java网络编程——对象的序列化与反序列化

当两个进程进行远程通信时&#xff0c;彼此可以发送各种类型的数据&#xff0c;如文本、图片、语音和视频等。无论是何种类型的数据&#xff0c;都会以二进制序列的形式在网络上传送。当两个Java进程进行远程通信时&#xff0c;一个进程能否把一个Java对象发送给另一个进程呢&a…

LeetCode 每日一题 Day 6(DFS+BFS)

1466. 重新规划路线 n 座城市&#xff0c;从 0 到 n-1 编号&#xff0c;其间共有 n-1 条路线。因此&#xff0c;要想在两座不同城市之间旅行只有唯一一条路线可供选择&#xff08;路线网形成一颗树&#xff09;。去年&#xff0c;交通运输部决定重新规划路线&#xff0c;以改变…

c语言词法分析器

词法分析器&#xff08;也称为词法解析器或词法扫描器&#xff09;是编译器的一个组成部分&#xff0c;它的任务是将输入的源代码&#xff08;字符流&#xff09;分解成称为“标记”的序列&#xff0c;其中每个标记对应于源代码中的一个单词或符号。 以下是一个简单的C语言词法…

12月7日作业

使用QT模仿一个登陆界面&#xff08;模仿育碧Ubisoft登录界面&#xff09; #include "myqq.h"MyQQ::MyQQ(QWidget *parent): QMainWindow(parent) {this->resize(880,550); //设置窗口大小this->setFixedSize(880,550); //固定窗口大小this->setStyleShee…

SpringMVC 案例

文章目录 前言1. 计算器1.1 准备前端代码1.2 测试前端代码1.3 完成后端代码1.4 验证程序 2. 留言板2.1 前端代码准备2.2 测试前端代码2.3 完成前后端交互代码2.4 完成后端代码2.5 案例测试2.6 完善前后端交互2.7 完善后端代码2.8 完整功能测试 lombok简单的方式添加Lombok工具3…