表达式求值(后缀表达式)

ops/2025/3/5 12:07:32/

后缀表达式

后缀表达式是给计算机去看的,一个个压进栈中; 遇到操作符就计算再将计算出的结果压到栈中;最后弹出结果。

1.栈的初始化(动态存储)

typedef struct {ElemType* data;int top;
}Stack;
//初始化
Stack* initStack()
{Stack* s = (Stack*)malloc(sizeof(Stack));s->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);s->top = -1;return s;
}

2.用了一个枚举类型去存储一些操作

typedef enum
{   //左右括号  LEFT_PARE, RIGTH_PARE,ADD,SUB,MUL,DIV,MOD,EOS,NUM 
}contentType;

3.对栈的入栈和出栈操作

// 入栈操作
int push(Stack* s, ElemType elem) {if (s->top == MAXSIZE - 1) {printf("栈满,无法入栈\n");return 0;}s->top++;s->data[s->top] = elem;return 1;
}
int pop(Stack* s, ElemType* elem) {if (s->top == -1) {printf("栈空,无法出栈\n");return 0;}*elem = s->data[s->top];s->top--;return 1;
}

4.对操作数的具体操作

  • 我们来模拟当index = 0时 在 字符数组中下标为0的字符是8 然后可以得到 symbol = '8'

  • 进入switch中可以返回NUM

  • 在eval函数中,token为NUM就识别为数字,就压栈

  • 不断的循环最后完成表达式求值

contentType getToken(char* symbol, int* index)
{*symbol = expr[*index]; //先将0的地址传过来现在值为8*index = *index + 1; //index变2switch (*symbol)//将8存进去{case'(':return LEFT_PARE;case')':return RIGTH_PARE;case'+':return ADD;case'-':return SUB;case'*':return MUL;case'/':return DIV;case'%':return MOD;case'\0':return EOS;default:return NUM;  //数字8 返回NUM}
}
​
int eval(Stack* s)
{char symbol;int op1, op2;int index = 0;contentType token; //字符的类型token = getToken(&symbol, &index);//识别到是哪个字符,返回什么算法ElemType result;while (token != EOS) {//一直循环到字符数组的\0结束if (token == NUM)//如果是数字就压栈{push(s, symbol - '0');// 字符减去'0' 是数值}else{pop(s, &op2); //如果是操作符就弹出进行计算pop(s, &op1);
​switch (token){case ADD:push(s, op1 + op2);break;case SUB:push(s, op1 - op2);break;case MUL:push(s, op1 * op2);break;case DIV:push(s, op1 / op2);break;case MOD:push(s, op1 % op2);break;default:break;}}token = getToken(&symbol, &index);
​}pop(s, &result);printf("%d\n", result);return 1;
}

5.一个全局变量,字符数组

char expr[] = "82/2+56*-";

完整代码如下

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef int ElemType;typedef struct {ElemType* data;int top;
}Stack;typedef enum
{	//左右括号	LEFT_PARE, RIGTH_PARE,ADD,SUB,MUL,DIV,MOD,EOS,NUM 
}contentType;char expr[] = "82/2+56*-";//初始化
Stack* initStack()
{Stack* s = (Stack*)malloc(sizeof(Stack));s->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);s->top = -1;return s;
}// 入栈操作
int push(Stack* s, ElemType elem) {if (s->top == MAXSIZE - 1) {printf("栈满,无法入栈\n");return 0;}s->top++;s->data[s->top] = elem;return 1;
}
int pop(Stack* s, ElemType* elem) {if (s->top == -1) {printf("栈空,无法出栈\n");return 0;}*elem = s->data[s->top];s->top--;return 1;
}
contentType getToken(char* symbol, int* index)
{*symbol = expr[*index]; //先将0的地址传过来现在值为8*index = *index + 1; //index变2switch (*symbol)//将8存进去{case'(':return LEFT_PARE;case')':return RIGTH_PARE;case'+':return ADD;case'-':return SUB;case'*':return MUL;case'/':return DIV;case'%':return MOD;case'\0':return EOS;default:return NUM;  //数字8 返回NUM}
}int eval(Stack* s)
{char symbol;int op1, op2;int index = 0;contentType token; //字符的类型token = getToken(&symbol, &index);//识别到是哪个字符,返回什么算法ElemType result;while (token != EOS) {//一直循环到字符数组的\0结束if (token == NUM)//如果是数字就压栈{push(s, symbol - '0');// 字符减去'0' 是数值}else{pop(s, &op2); //如果是操作符就弹出进行计算pop(s, &op1);switch (token){case ADD:push(s, op1 + op2);break;case SUB:push(s, op1 - op2);break;case MUL:push(s, op1 * op2);break;case DIV:push(s, op1 / op2);break;case MOD:push(s, op1 % op2);break;default:break;}}token = getToken(&symbol, &index);}pop(s, &result);printf("%d\n", result);return 1;
}
int main()
{Stack* s = initStack();eval(s);
}


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

相关文章

【蓝桥】常用库函数

1、memset()函数 1.1 基本介绍 定义在头文件<cstring>中主要作用是对一块内存区域进行设置值的操作 1.2 函数原型 void *memset(void *str, int c, size_t n);str&#xff1a;指向要填充的内存块的指针c&#xff1a;要设置的值。该值以int形式传递&#xff0c;但函数在…

玩转顺序表:用 C 语言实现数据的插入与删除

目录 顺序表的定义 插入元素 删除元素 查找元素 主函数 打印顺序表 完整代码 总结 在这篇博客中&#xff0c;我们将探讨如何使用 C 语言实现一个简单的顺序表&#xff08;也称为动态数组&#xff09;&#xff0c;并实现一些基本操作&#xff0c;包括插入、删除和查找…

ldap放大 DDOS.c

ldap放大汉化源码 安装环境指令: 乌班图/Debian系统: apt install gcc -y centos系统: yum install gcc -y 编译指令: gcc ldap.c -o ldap -pthread -stdgnu99 最后输入 ./ldap 查看使用方法 注意:本脚本完全开源免费,请勿使用任何已编译版本,使用本脚本必须拥有roo…

京东一面:为什么 IDEA 建议去掉 StringBuilder,而要使用 “+” 拼接字符串?

本文已收录至Java面试网站&#xff1a;https://topjavaer.cn 今天咱们来聊聊一个很常见的开发场景&#xff1a;字符串拼接。在日常开发中&#xff0c;字符串拼接几乎是每个 Java 开发者都会用到的操作。但最近&#xff0c;有朋友在面试时被问到一个问题&#xff1a;“为什么 ID…

Zookeeper 及 基于ZooKeeper实现的分布式锁

1 ZooKeeper 1.1 ZooKeeper 介绍 ZooKeeper是一个开源的分布式协调服务&#xff0c;它的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来&#xff0c;构成一个高效可靠的原语集&#xff0c;并以一系列简单易用的接口提供给用户使用。 原语&#xff1a;操作系统或…

IDEA中Git版本回退终极指南:Reset与Revert双方案详解

目录 前言一、版本回退前置知识二、Reset方案&#xff1a;整体改写历史1、IDEA图形化操作&#xff08;推荐&#xff09;1.1、查看提交历史1.2、选择目标版本1.3、选择回退模式1.3.1、Soft&#xff08;推荐&#xff09;1.3.2、Mixed1.3.3、Hard&#xff08;慎用&#xff09;1.3.…

Qt中如何从头到尾自定义设计一个标题栏

使用qt的widget自定义设计标题栏 头文件TitleBar.h #pragma once#include <QWidget> #include<QLabel> #include<QPushButton>enum ButtonType {MIN_BUTTON 0,MIN_MAX_BUTTON,ONLY_CLOSE_BUTTON };class TitleBar : public QWidget {Q_OBJECTpublic:Titl…

DiffBoost:通过文本引导的扩散模型增强医学图像分割

简介 本推文介绍了一篇来自美国西北大学&#xff0c;机器与混合智能实验室的论文《DiffBoost: Enhancing Medical Image Segmentation via Text-Guided Diffusion Model》&#xff0c;发表在医学图像处理领域的顶级期刊《IEEE Transactions on Medical Imaging》。论文中提出了…