逆波兰式的实现及表达式的值

2023-05-16

逆波兰式的实现

1、概念

逆波兰式也叫后缀表达式,这里先简单帮大家理解一下概念性问题。
像我们平常使用到的表达式如 ( a + b ) ∗ c 、 2 + 5 ∗ 3 (a+b)*c、2+5*3 (a+b)c2+53等都是中缀表达式,对我们来说是最能理解的,但是计算机则理解起来比较困难,而其相应的后缀表达式为 a b + c ∗ 、 253 ∗ + ab+c*、253*+ ab+c253+则更好的便于计算机的理解和处理。最直观的是用树来给大家展示:
(以 ( a + b ) ∗ c (a+b)*c (a+b)c为例)

在这里插入图片描述
通过图片发现,对树进行中序遍历得到的就是中缀表达式;对树进行后序遍历得到的就是后缀表达式,这也就是其名字的由来。想必大家一定恍然大悟了吧(嘻嘻)。

2、算法实现

1、逆波兰式

首先需要一个初始字符串、输出字符串和一个栈
对初始字符串的每一个字符进行如下处理:

  1. if 该字符是操作符,则直接符给输出字符串
  2. if 该字符是‘(’,则压入栈中
  3. if 该字符是‘)’,则将栈中从栈顶到最近的‘(‘之间的字符全部出栈赋给输出字符串
  4. while该字符是运算符:
    if 栈为空或栈顶元素为’(‘或栈顶元素优先级高于该字符if栈为空或栈顶元素为’(‘或栈顶元素优先级低于该字符,将该字符压入栈中;break结束while操作
    else 将栈顶元素出栈,赋给输出字符串,继续while操作
  5. 重复1-4的操作直到所有初始字符串均已处理
  6. 若栈中尚有元素,则将其栈内所有元素出栈,赋给输出字符串
  7. 输出输出字符串
  8. 操作结束
注: 在进行字符串的转换之前,先进行一次判断,也就是表达式第一个数是否是负数(即第一个字符是否为‘-’), 若是,须在‘-’前插入一个0,在进行之后的转换操作,反之,字符不做改动。

2、表达式的值

在计算过逆波兰式的基础上来求解表达式的值,计算表达式的结果。
对逆波兰式操作后获得的字符串的每个字符进行如下处理:

  1. if 字符是操作符,则压入栈中
  2. if 字符为运算符,则取出栈中最高两位进行该运算符的运算,然后将计算结果再存入栈中
  3. 重复1-2操作直到所有字符拘役处理
  4. 输出栈中余下的操作数(表达式的最终结果)
  5. 操作结束

3、代码实现

#include<stdio.h>
#include<malloc.h>
#include<string.h>

//定义栈 
typedef struct{
	char data[100];
	int top;
	int bottom;
}stack;

//定义全局变量 
char str[10];
int n=0;
	
//创建栈
stack *StackCreate(){
	stack *p=(stack*)malloc(sizeof(stack));//分配新空间 
	if(p==NULL)//分配失败 
	return 0;
	p->bottom=p->top=0;//分配成功 
	return p;
}

//入栈
void StackInput(stack *p,char str){
	p->data[p->top]=str;//存入栈中 
	p->top++;//栈顶指针加1 
	//printf("%c",p->data[p->top-1]);
} 

//出栈 
char StackOutput(stack *p,char sp){
	if(p->top!=p->bottom){//栈非空 
		sp=p->data[p->top-1];//栈顶内容输出 
		p->top--;//栈顶减1 
		//printf("%c",str);
		return sp;
	}
} 

//优先级比较
int prior(char a){
	if(a=='+'|a=='-')
	return 1;
	else if(a=='*'|a=='/')
	return 2;
	else 
	return 0;
} 

//逆波兰式 
void rpn(char *s,stack *p){
	int i,j;
	char sp;
	if(s[0]=='-'){//若第一个数为负数,则在其前面加一个0 
		for(i=0;i<strlen(s);i++)
		s[strlen(s)-i]=s[strlen(s)-i-1];
		s[0]='0';
	}
	for(i=0;i<strlen(s);i++){
		if(s[i]>='0'&&s[i]<='9'){//s[i]是操作数
			str[n++]=s[i];
		}
		if(s[i]=='('){//s[i]是左括号 
			StackInput(p,s[i]);
		}
		if(s[i]==')'){//s[i]是右括号 
			while(p->data[p->top-1]!='('){
				str[n++]=p->data[p->top-1];
				p->top--;
			}
			p->top--;
		}
		while(s[i]=='+'|s[i]=='-'|s[i]=='*'|s[i]=='/'){//s[i]是运算符 
		    if(p->bottom==p->top|p->data[p->top-1]=='('|prior(s[i])>prior(p->data[p->top-1])){//若栈是空 或 栈顶为( 或 s[i]优先级高于栈顶元素,则入栈 
			    StackInput(p,s[i]);
			    break;
			}
			else//反之栈顶元素出栈,继续while循环 
			str[n++]=StackOutput(p,sp);
		}	 
	}
	while(p->bottom!=p->top){//若栈未空,将剩余的字符输出 
		str[n++]=p->data[p->top-1];
		p->top--;
	}
} 

//计算表达式的值
void result(stack *p,char *str){
	int i,j=0;
	char sp,m,n;
	for(i=0;i<strlen(str);i++){
		if(str[i]>='0'&&str[i]<='9')//若为操作数,直接压入战中 
		StackInput(p,str[i]);
		while(str[i]=='+'|str[i]=='-'|str[i]=='*'|str[i]=='/'){//若为运算符,从栈中取出两个进行运算,将结果再存入栈中 
			m=p->data[p->top-1];//栈顶 
		    n=p->data[p->top-2];//栈顶下一个 
		    p->top=p->top-2;
		    if(str[i]=='+')
		    j=((int)n-48)+((int)m-48);
		    if(str[i]=='-')
		    j=((int)n-48)-((int)m-48);
		    if(str[i]=='*')
		    j=((int)n-48)*((int)m-48);
		    if(str[i]=='/')
		    j=((int)n-48)/((int)m-48);
		    StackInput(p,(char)(j+48));//将结果再存入栈中 
		    break;
		}	
	}
	printf("\n表达式的值为:\n%d",(int)p->data[p->top-1]-48);//读出最后的值 
} 

//主函数 
int main(){
	int i,j;
	int r;
	stack *p;//定义栈名 
	p=StackCreate();//创建栈 
	char s[10];
	printf("输入中缀表达式:\n");
	scanf("%s",s);
	rpn(s,p);//调用逆波兰式 
	printf("逆波兰式为:\n");
	for(i=0;i<n;i++)//输出逆波兰式  
	printf("%c",str[i]);
	result(p,str);//进行求解表达式的值 
}









//大家注入输入表达式的时候,括号千万要区分中英文,谨记



代码注释的很清楚明了,希望大家能够真正明白理解,若有何疑问请留下评论,第一时间看到就会回复。
在这里插入图片描述

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

逆波兰式的实现及表达式的值 的相关文章

随机推荐

  • PyQGIS获取要素以及要素中的几何属性

    from qgis core import QgsProject QgsVectorLayer 1 指定输入图层路径 path to airports layer 61 r 34 E PyQGIS Source Data Ex5 pt sh
  • 【解决思路】当前不会命中断点,还未为文档加载任何符号

    问题 xff1a 在调试代码过程中 xff0c 计算机突然蓝屏而强制关闭并重启 xff0c 以至于vs在运行调试的过程中就在非正常的情况下被迫关闭 重启之后 xff0c 继续打开并运行项目 xff0c 却发现无法进行调试代码 于是我把鼠标移
  • PyQGIS获取字段列表

    from qgis core import QgsVectorLayer QgsProject path to airports layer 61 r 34 E PyQGIS Source Data Ex5 pt shp 34 layer
  • 【用示例学习与理解C++系列】类的构造方法

    前言 本文主要是通过简单的示例 xff0c 去学习与理解C 43 43 类的构造方法 构造方法的作用 为什么存在构造方法 xff1f 为什么需要构造方法 xff1f 那是因为当我们在代码中定义一类变量 xff08 实例化一个类的实例 对象时
  • CSP-M2 :神奇的序列

    文章目录 HRZ的序列题目输入输出解题代码 HRZ学英语 滑动窗口题目输入输出解题代码 咕咕东的奇妙序列题目输入输出解题代码 HRZ的序列 题目 相较于咕咕东 xff0c 瑞神是个起早贪黑的好孩子 xff0c 今天早上瑞神起得很早 xff0
  • 转化Foggy_Cityscapes数据集为voc和yolo格式用作目标检测

    目录 一 数据集下载 xff08 1 xff09 解压后文件夹目录 xff08 2 xff09 gtFine格式如下所示 xff1a 二 转换为VOC数据集格式 xff08 1 xff09 生成xml标签 xff08 2 xff09 将le
  • 如何获取数据库的逻辑文件名、数据库文件的路径

    1 sp helpdb 数据库名 2 获取数据库文件路径 select ltrim rtrim filename from 数据库名 sysfiles where charindex 39 MDF 39 filename gt 0 sele
  • Linux进度条以及makefile相关知识

    一 在Linux环境下实现进度条 xff0c 其原理是 xff1a 用sleep函数或usleep函数控制每隔多长时间输出一次 xff0c 每次输出字符会比上次输出字符多一个 在此代码中 xff0c 用 r而不用 n的原因 xff1a n表
  • hdu - 4642 - Fliping game(博弈)

    题意 xff1a Alice和Bob玩游戏 xff0c 一个N M的矩阵 xff0c 里面是1或0 xff0c 每人每次选择一个1的位置 xff0c 然后将这个位置到右下角的整个矩形元素全部取反 xff08 1变0 xff0c 0变1 xf
  • 图形界面报错“已拒绝X11转移申请”的解决方法

    今天想通过本机给虚拟机起x manager图形界面的时候报出 解决办法 xff1a 原来X11 forwarding依赖 xorg x11 xauth 软件包 xff0c 所以必须先安装 xorg x11 xauth 软件包 yum ins
  • bash: ifconfig: command not found 解决办法

    经常遇到 34 bash xxxx command not found 34 这样的问题 xff0c 用root用户也不行 xff0c 在网上查阅了此问题 xff0c 解决方法如下 xff1a 原文1 http hi baidu com j
  • 用CMfcShellTree和CMFCShellListCtrl实现资源管理器并过滤扩展名

    资源管理器 CMfcShellTree和CMFCShellListCtrl是VS2008 SP1和VS2010内自带的控件 xff0c 用这两个控件实现资源管理器只需几行代码 CMFCShellTreeCtrl m tree CMyShel
  • 解决虚拟机下CentOS系统无法识别usb设备

    其实不是什么 解决 xff0c 虚拟机默认是自动挂载usb设备的 只是要注意插usb设备的时候 xff0c 虚拟机必须要处于当前窗口 然后就会自动弹出已安装好usb设备的提示 xff08 如果系统比较卡 xff0c 需要多等一会 xff09
  • 基于MDK的汇编语言编写及小灯闪烁的汇编程序实现

    基于MDK的STM32汇编语言编写及小灯闪烁的汇编程序实现 一 新建工程二 配置环境1 选择设备2 选择运行环境3 添加源文件 三 测试代码1 源码2 仿真器设置3 编译调试 四 HEX文件解读五 闪烁LED的程序六 总结参考 一 新建工程
  • WIndows10连接虚拟机显示connection confused

    Windows10连接虚拟机显示connection confused 当我们想由win10连接虚拟机终端时 xff0c 使用第三方软件Putty或者win10的cmd都可能出现connection confused问题 xff0c 解决这
  • 交换两个数字(不使用其他变量)

    面试题 交换两个数字 xff08 不使用其他变量 xff09 一 题目要求 xff1a 有两个整数变量a 61 6 b 61 100不使用其他变量 xff0c 交换两个变量的值 二 解法 解法1 xff08 使用其他变量 xff09 xff
  • unity如何使用电脑模拟VR环境

    unity如何通过VRTK模拟VR环境 如何在没有HTC VIVE的前提下使用VR xff1f 由于作者研究室课题是基于虚拟现实的人机交互 xff0c 需要用到VR下的场景 xff0c 但由于实验室设备只有一套 xff0c 而当我们想要随时
  • 笔试算法:青蛙跳台阶

    笔试算法 xff1a 青蛙跳台阶 1 题目表述 假设青蛙正在跳台阶 需要 n 阶你能到达楼顶 每次青蛙可以跳 1 或 2 个台阶 xff0c 但不可以连续跳2个 请问有多少种不同的方法可以到楼顶呢 xff1f 注意 xff1a 给定 n 是
  • 输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数

    输入一行字符 xff0c 分别统计出其中英文字母 空格 数字和其他字符的个数 首先需要判断各自所出的范围 xff1a 中英文字母 xff1a a到z A到Z 空格 xff1a 空一个字符 数字 xff1a 1 9 然后则对一串字符进行逐个比
  • 逆波兰式的实现及表达式的值

    逆波兰式的实现 1 概念 逆波兰式也叫后缀表达式 xff0c 这里先简单帮大家理解一下概念性问题 像我们平常使用到的表达式如 a 43 b c