利用栈来完成表达式求值

2023-11-11

利用栈来完成表达式求值

一个表达式要求值,分为操作数部分和运算符部分,求值的过程便是运算符对操作数进行操作。
首先我们定义两个栈,一个栈存放运算符,先放个#进去,代表开始,然后记得结束最后一个字符也是#,这样代表结束。然后建立一个栈存放操作数。
算法:
定义一个字符来getchar字符,然后判断。首先判断这是字符是不是#或者现在运算符栈的top是不是#,如果两个都是#那么运算完成。
然后判断,不是运算符的话就存入操作数栈内
如果是运算符,那么判断,这个运算符与现在运算符栈top位置的运算符的关系,两者的优先性,根据优先性来进行下一步操作
比如top位置是‘-‘,然后字符是‘)’,那么在运算符栈内肯定有一个“(”与字符‘)’对应,如果没有,那么肯定输入有问题。因为有’(‘在栈内所以‘-’的优先性是大于‘)’的,获得字符‘>’所以进行运算,也就是减。首先从操作数里面取top出来,作为减数,然后top–,然后再取top作为被减数,因为存放顺序的关系,先进去的肯定是在前面。然后在字符“>”的情况下是不进行getchar的,因为也就进行了运算,所以现在字符还是‘)’,然后现在运算符栈内的就是‘(’,如果不是,那么继续运算,因为可能出现(7+2+2)这种,那么多算一次‘>’的情况就行。然后(与)判断结果是=,让运算符栈内(消掉,然后现在括号内的运算已经完毕,然后getchar获取下一个字符,继续进行判断!

代码可以直接运行

#include"consts.h"

typedef struct {
	char S[100];
	int top;
}CHARStack;

void InitStack(CHARStack *S) {
     S->top = -1;
}
void Push(CHARStack* S, char ch) {
	if (S->top >= 99) {
		printf("栈满!\n");
		exit(0);
	}
	else {
		S->top++;
		S->S[S->top] = ch;
	}
}
char GetTop(CHARStack* S) {
	if (S->top==-1) {
		printf("栈空!\n");
		exit(0);
	}
	else {
		
		return S->S[S->top];
	}
}

int TRIn(char ch) {                           //是运算符就返回1,不是运算符返回0
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#') {
		return 1;
	}
	else return 0;
}


char Precede(char ch1, char ch2) {
	if (ch1 == '+') {
		if (ch2 == '+')return '>';
		if (ch2 == '-')return '>';
		if (ch2 == '*')return '<';
		if (ch2 == '/')return '<';
		if (ch2 == '(')return '<';
		if (ch2 == ')')return '>';
		if (ch2 == '#')return '>';
	}
	else if (ch1 == '-') {
		if (ch2 == '+')return '>';
		if (ch2 == '-')return '>';
		if (ch2 == '*')return '<';
		if (ch2 == '/')return '<';
		if (ch2 == '(')return '<';
		if (ch2 == ')')return '>';
		if (ch2 == '#')return '>';
	}
	else if (ch1 == '*') {
		if (ch2 == '+')return '>';
		if (ch2 == '-')return '>';
		if (ch2 == '*')return '>';
		if (ch2 == '/')return '>';
		if (ch2 == '(')return '<';
		if (ch2 == ')')return '>';
		if (ch2 == '#')return '>';
	}
	else if (ch1 == '/') {
		if (ch2 == '+')return '>';
		if (ch2 == '-')return '>';
		if (ch2 == '*')return '>';
		if (ch2 == '/')return '>';
		if (ch2 == '(')return '<';
		if (ch2 == ')')return '>';
		if (ch2 == '#')return '>';
	}
	else if (ch1 == '(') {
		if (ch2 == '+')return '<';
		if (ch2 == '-')return '<';
		if (ch2 == '*')return '<';
		if (ch2 == '/')return '<';
		if (ch2 == '(')return '<';
		if (ch2 == ')')return '=';
		if (ch2 == '#') {
			printf("输入的多项式有误!\n");
			exit(0);
		}
	}
	else if (ch1 == ')') {
		if (ch2 == '+')return '>';
		if (ch2 == '-')return '>';
		if (ch2 == '*')return '>';
		if (ch2 == '/')return '>';
		if (ch2 == '(') {
			printf("输入的多项式有误!\n");
			exit(0);
		}
		if (ch2 == ')')return '>';
		if (ch2 == '#')return '>';
	}
	else if (ch1 == '#') {
		if (ch2 == '+')return '<';
		if (ch2 == '-')return '<';
		if (ch2 == '*')return '<';
		if (ch2 == '/')return '<';
		if (ch2 == '(')return '<';
		if (ch2 == ')') {
			printf("输入的多项式有误!\n");
			exit(0);
		}
		if (ch2 == '#')return '=';
	}
	else {
		printf("出错!");
		exit(0);
		return 0;
	}
}

void Pop(CHARStack* S, char* ch) {
	if (S->top == -1) {
		printf("栈空!\n");
		exit(0);
	}
	else {
		*ch=S->S[S->top];
		S->top--;
	}
}

int changchartonumber(char ch) {
	if (ch == '0') {
		return 0;
	}
	else if (ch == '1') {
		return 1;
	}
	else if (ch == '2') {
		return 2;
	}
	else if (ch == '3') {
		return 3;
	}
	else if (ch == '4') {
		return 4;
	}
	else if (ch == '5') {
		return 5;
	}
	else if (ch == '6') {
		return 6;
	}
	else if (ch == '7') {
		return 7;
	}
	else if (ch == '8') {
		return 8;
	}
	else if (ch == '9') {
		return 9;
	}
	else {
		
		return (int)ch;
		
	}
}
char Operate(char ch1, char theta, char ch2) {
	int c1, c2;
	c1 = changchartonumber(ch1);
	c2 = changchartonumber(ch2);
	
	if (theta == '+') {
		return c1 + c2;
	}
	else if (theta == '-') {
		return c1 - c2;
	}
	else if (theta == '*') {
		return  c1 * c2;
	}
	else if (theta == '/') {
		return c1 / c2;
	}
	else {
		printf("错误");
		exit(0);
		return '0';
	}

}

int main() {
	char c,theta,a,b,xl,p;
	int x;
	CHARStack *OPTR, *OPND;                      //定义OPTR为运算符栈,OPND为运算数栈
	OPTR = (CHARStack*)malloc(sizeof(CHARStack));
	OPND = (CHARStack*)malloc(sizeof(CHARStack));
	InitStack(OPTR);
	Push(OPTR,'#');
	InitStack(OPND);
	c = getchar();
	while (c != '#' || GetTop(OPTR) != '#') {
		if (!TRIn(c)) {                    //不是运算符
			Push(OPND, c);
			c = getchar();
		}
		else {
			switch (Precede(GetTop(OPTR),c))
			{
			case'<'://栈顶元素优先权低
				Push(OPTR, c); c = getchar(); break;
			case'='://脱括号并接受下一个字符
				Pop(OPTR, &p); c = getchar(); break;
			case'>'://栈顶元素优先权高
				
				Pop(OPTR, &theta);
				Pop(OPND, &b);
				Pop(OPND, &a);
			
				Push(OPND, Operate(a, theta, b));
				break;
			}
		}
	}
	printf("结果为:%d",(int)OPND->S[OPND->top]);
	return 0;
}

头文件

#pragma once
#include<stdio.h>                        //EOF(=^Z或F6),NULL
#include<malloc.h>                       //malloc()等
#include<limits.h>                       //INT_MAX等
#include<string.h>                       
#include<stdlib.h>                       //atoi()
#include<io.h>                           //eof
#include<math.h>                         //floor(),ceil(),abs()*
#include<process.h>                      //exit()*
/*函数结果状态代码*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR -1
#define INFEASIBLE -1


在这里插入图片描述

这个过程当中其实需要两个类型栈来进行运算的,但是我图方便就按一个类型就是char类型进行运算,然后根据ASCII码与数字的关系,灵活转换,就可以达到两个类型栈的效果。比如字符‘5’-‘2’两个字符相减结果肯定是ASCII码,但由于位置的特殊性,结果还是3,但是这种算法是错误的。因为实际上是53-50=3;这个过程我利用一个changchartonumber函数,让他们变成int值直接的运算,要不然‘5’+‘2’实际上是53+50,结果是无法估计的!然后根据直接把结果存放在栈内。比如结果3,我直接把3存放在内,但是3代表的字符是未知的对于我来说,那么输出结果的时候,可以直接(int)强制转型,输出的便是3.其实char型的本质是int型,ASCII码表就是对于int与char之间的关系,多理解就可以了

本人在校大学生,菜鸟学习中,欢迎大佬指导,欢迎大家点赞关注!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用栈来完成表达式求值 的相关文章

随机推荐

  • python自动化:列表的处理

    用到的第三方库 用于判断是否可迭代的库 from collections import Iterable def getCount list0 value 功能 统计元素出现的次数 仅支持字符串或数组统计 param list0 可迭代数据
  • angular:css row-gap作用

    问题 如题 解决 row gap可以使用于网格布局 也可以使用于flex布局 调整行间距
  • python 读写csv文件(创建,追加,覆盖)

    总述 这篇博客讲述python怎样创建 读写 追加csv文件 创建 利用csv包中的writer函数 如果文件不存在 会自动创建 需要注意的是 文件后缀一定要是 csv 这样才会创建csv文件 这里创建好文件 将csv文件的头信息写进了文件
  • Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by serv

    node 使用mysqljs链接Mysql数据库时报以下错误 原因是mysql8 0更改了密码默认的认证插件为Caching sha2 password 原来是mysql native password 更改密码为mysql native
  • 互联网摸鱼日报(2023-04-30)

    互联网摸鱼日报 2023 04 30 InfoQ 热门话题 被ChatGPT带火的大模型 如何实际在各行业落地 Service Mesh的未来在于网络 百度 Prometheus 大规模业务监控实战 软件技术栈商品化 应用优先的云服务如何改
  • 【Selenium】获取属性

    文章目录 1 获取窗体属性 1 1 获取网页标题 1 2 获取网址 1 3 获取浏览器名称 1 4 获取网页源码 2 获取元素属性 2 1 获取元素的文本内容 2 2 获取元素属性 2 3 获取其他属性 1 获取窗体属性 1 1 获取网页标
  • 深度学习笔记二:多层感知机(MLP)与神经网络结构

    为了尽量能形成系统的体系 作为最基本的入门的知识 请参考一下之前的两篇博客 神经网络 一 概念 神经网络 二 感知机 上面的两篇博客让你形成对于神经网络最感性的理解 有些看不懂的直接忽略就行 最基本的符号的记法应该要会 后面会用到一这两篇博
  • SpringBoot整合SpringSecurity认证与授权

    唠嗑部分 在项目开发中 权限认证是很重要的 尤其是一些管理类的系统 对于权限要求更为严格 那么在Java开发中 常用的权限框架有哪些呢 推荐的有两种 Shiro 与 SpringSecurity 当然也可以结合切面自己实现 Shiro是Ap
  • 算法分析与设计编程题 递归与分治策略

    棋盘覆盖 题目描述 解题代码 para 棋盘 行偏移 列偏移 特殊行 特殊列 void dividedCovering vector
  • BifroMQ:五分钟了解百度开源旗下消息中间件

    BifroMQ 并不是一个独立的公司 而是由一家名为 Bifrost 的公司开发的一款产品 Bifrost 公司成立于 2014 年 总部位于中国北京 是一家专注于开源技术的公司 当时 Bifrost 公司的创始人陈明发起了开源项目 iPr
  • 一步步开发自己的OS操作系统

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 以MSP430单片机为例控制4个灯以不同频率闪烁 把原理搞清楚了一通则百通 可以举一返三 注 以下所讲的堆栈即栈 因为堆栈说习惯了 堆是堆栈是栈 MSP430有16个寄存器
  • 关于linux服务器上生成的图片中文字为的乱码问题

    一 功能描述 linux服务器后端生成图表 使用了canvas和echarts 并将生成的图片发送到企业微信群里 二 出现的问题 生成的图表中文展示不出来 是乱码 错误图表展示如下 三 文字乱码出现的原因 linux服务器没有对应的文字 四
  • mysql删除以什么开头的数据_Mysql如何删除以“#sql-”开头的临时表

    MySQL如何删除以 sql 开头的临时表 现象 在重建索引后 发现Mysql服务器的磁盘空间快满了 在用如下命令重建索引 mysql gt alter table skatetab add unique index id uid drop
  • java agentlib jdwp,JDWP无依赖攻击

    JDWP JDWP 是 Java Debug Wire Protocol 的缩写 在JPDA Java Platform Debugger Architecture 中 它定义了调试器 debugger 和被调试的 Java 虚拟机 tar
  • LevelHelper-NG

    LevelHelper 的克隆 放在 github上 自取 放一张谍照 Qt4 8 4 vs2010
  • 一些简单的变量以及C语言的基本格式

    一些比较关键的操作 枚举关键 enum MALE REMALE SECRET叫做枚举变量 scanf是C语言提供的 scanf 不是标准C语言提供的而是VS编译器提供的 尽量不要使用会使程序失去可移植性 define CRT SECURE
  • 空时自适应处理用于机载雷达——空时处理基础知识(Matla代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 2 1 机载阵列雷达信号环境 2 2 空时处理基础知识 2 3 元素空间空时自适应处理 2
  • 一文了解游戏美术开发流程,以及可能遇到的问题

    想了解典型的游戏资产开发工作流吗 一个团队的游戏美术流程取决于几个因素 包括游戏开发工作室类型 正在开发的游戏类型和开发团队成员的数量等 继续往下阅读 你能了解游戏美术开发流程 所使用的工具 以及可能出现的问题 什么是游戏资产工作流 游戏资
  • windows10内置的Ubuntu系统 开启浏览器界面,安装Xming

    1 安装Xming 2 安装完直接打开 Xming 即可 3 安装一个firefox测试 apt get install firefox 4 运行 在程序指令前加上 DISPLAY 0 DISPLAY 0 firefox 5 简化配置 每次
  • 利用栈来完成表达式求值

    利用栈来完成表达式求值 一个表达式要求值 分为操作数部分和运算符部分 求值的过程便是运算符对操作数进行操作 首先我们定义两个栈 一个栈存放运算符 先放个 进去 代表开始 然后记得结束最后一个字符也是 这样代表结束 然后建立一个栈存放操作数