数学表达式的处理

news/2024/11/27 20:37:08/

概述

在OJ上 会遇到一些这样的题目:

小明同学写数学四则运算,有把括号写多、写少、写错的情况,比如(A+B)*(C-D ,请你输入一个表达式,判断此表达式的括号是否正确(不考虑运算的结果正确性)。

每次我看到 "括号"、算数表达式,我的第一反应就是 栈、树遍历,逆波兰表达式这些概念。

此文,我们就来探讨一下这类算法的使用。

一、栈

此处我就不想太过深入的讲解其原理了,都是数据结构基础,知道它是FILO的就行了。

栈本质上来说,是一个线性表,存储结构可以是顺序的(连续内存划分),也可以是链表

栈是允许在同一端进行插入和删除操作的特殊线性表。

允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);

栈底固定,而栈顶浮动;

栈中元素个数为零时称为空栈。

插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为先进后出表。

1、我们在什么情况下会用到栈? 

在JVM中,我们常听说 虚拟机栈的概念,虚拟机栈是存在于运行时数据区的一个逻辑单元,它由一个个栈帧(Stack frame)构成,在当前线程中,每进行一次函数调用,就会形成一个栈帧。当进行一次方法调用,虚拟机会压入一个栈帧、方法结束的时候,会弹出该栈帧。

比如 方法 m1,m2, m3

m3 调用m2 ,m2 调用m1,我们进行一次测试:

package com.huawei.oj;/*** @Title:* @Description: Method called ,JVM stack Frame struct* @author: Alex* @Version:* @date 2023-01-22-8:20*/
public class StackDemo {public static void main(String[] args) {m3();}public static int m1(){System.out.println("m1 开始");int i=10;System.out.println("m1 结束");return i;}public static int m2(){System.out.println("m2开始");int i = m1();System.out.println("m2结束");return i;}public static int m3(){System.out.println("m3开始");int i = m2();System.out.println("m3结束");return i;}
}

 Debug我们看到,函数调用(压栈)顺序  Main---->m3 ------>m2---->m1

输出结果,我们也能看到压栈和弹栈的顺序,也是满足  FILO的:

 

2、为什么说到栈?

前面说的这道题,最典型的解题思路,就是栈。

思路:

判断表达式的括号是否正确:

1、括号的数量是对称相等的(这一步判断并不是必须的,因为2,和3 其实可以完全涵盖1)

2、每个左括号,后面必然有一个右括号等待与之匹配

3、不能以右括号 )开头,或者以左括号 )结尾

这里对第二点进行补充:

左括号之后并不一定就是右括号,因为会有括号嵌套的现象,比如   ((A+B)*C) -D)

满足上述几个条件后,我们用栈去解答如何设计算法:

设计算法:

1、遍历表达式字符串

2、遇见左括号就压栈,

3、遇见右括号,先判断栈是否为空,不为空就弹栈,为空,直接返回“表达式书写错误”

4、遍历完成,判断栈是否为空,为空,返回表示表达式正确,不为空,说明栈内还有左括号,返回表达式书写错误

具有代码实现:

package com.huawei.oj;import java.util.Scanner;
import java.util.Stack;/*** @Title:* @Description: TODO* @author: Alex* @Version:* @date 2023-01-22-8:48*/
public class Express {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String str = scanner.nextLine();Stack<String> stack = new Stack<>();for(int i=0;i<str.length();i++){boolean isempty = stack.isEmpty();boolean isEqualR = ')'==str.charAt(i);boolean isEqualL = '('==str.charAt(i);if(isempty&&isEqualR) {  //空栈,右括号开头,或者多了一个右括号System.out.println("表达式不正确");return;}if(isEqualL){ //遇见左括号 压栈stack.push("(");}if(!isempty&&isEqualR){  //正常匹配,遇见右括号 弹栈stack.pop();}}if(stack.isEmpty()){ //输出判定: 最终栈空 正确 ;非空 括号数量不对System.out.println("表达式正确");}elseSystem.out.println("表达式不正确");}
}

3、关于二叉树的遍历和中缀、前缀 后缀表达式


http://www.ppmy.cn/news/18634.html

相关文章

Word2Vec与文章相似度--相似度计算

2.7.4.2 相似度计算 目的&#xff1a;计算18号Python频道的文章之间相似度步骤&#xff1a; 1、读取数据&#xff0c;进行类型处理(数组到Vector)2、BRP进行FIT 读取数据&#xff0c;进行类型处理(数组到Vector) from pyspark.ml.linalg import Vectors # 选取部分数据做测试…

Linux系统之Bonding 网卡绑定配置方法

Linux系统之Bonding 网卡绑定配置方法一、检查本地系统环境1.检查系统版本2.查看服务器网卡二、创建网卡配置文件1.进入网卡配置文件目录2.拷贝eth0的网卡配置文件3.修改bond0网卡配置文件4.修改eth1网卡配置文件5.修改eth2网卡配置文件三、创建bonding的配置文件1.编辑bonding…

Java之Io知识详解 (二)

常见类使用常见类使用IO常见类的使用File相关字节流相关实现逐行输出文本文件的内容Java 中的网络支持InetAddressURLSocketsJava 7 文件操作介绍文件路径文件操作文件属性文件列表流文件监视常见类使用 本文主要介绍Java IO常见类的使用&#xff0c;包括&#xff1a;磁盘操作&…

Arduino的nodemcu 8266开发板使用MicroPython开发的整体流程

程序安装准备 安装开发板驱动&#xff0c;官网&#xff1a;&#xff08;https://cn.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tabdownloads&#xff09;这里不是CH340驱动&#xff0c;而是CP210x USB to USART 驱动&#xff0c;最终也是在“设备管理器查看COM口…

29. CSS简介:PyQuery模块的铺垫

目录 什么是 CSS&#xff1f; CSS 演示 - 一张 HTML 页面 - 多个样式&#xff01; 为何使用 CSS&#xff1f; CSS 实例 CSS 解决了一个大问题 CSS 节省了大量工作&#xff01; 通俗的解释 CSS 选择器 CSS 元素选择器 实例 CSS id 选择器 实例 CSS 类选择器 实例 …

自定义类型:结构体,枚举,联合

目录一、结构体内存对齐二、位段2.1 什么是位段2.2 位段内存分配规则2.3 位段的跨平台问题三、枚举四、联合体4.1 联合类型的定义4.2联合的特点4.3 联合大小的计算4.4 练习一、结构体内存对齐 struct s {char c1;int i;char c2; }; int main() {printf("%d\n", size…

07.C语言文件操作

1. 使用文件的原因我们前面学习结构体时&#xff0c;写了通讯录的程序&#xff0c;当通讯录运行起来的时候&#xff0c;可以给通讯录中增加、删除数据&#xff0c;此时数据是存放在内存中&#xff0c;当程序退出的时候&#xff0c;通讯录中的数据自然就不存在了&#xff0c;等下…

初识 Bootstrap4(前端开发框架)

初识 Bootstrap&#xff08;前端开发框架&#xff09;参考Bootstrap特点获取目录结构jQuery 与 Popper准备工作包含 jQuery 与 Poppermetabox-sizing基本模板无注释版本注释版本参考 项目描述Bootstrap 官方教程https://getbootstrap.net/docs/getting-started/introduction/百…