栈的简单应用(利用Stack进行四则混合运算)(JAVA)

news2024/12/26 23:49:22

目录

中缀表达式转后缀表达式

图解

代码实现过程:

完整代码: 

利用后缀表达式求值:

完整代码:


 

首先我们得先了解逆波兰表达式

中缀表达式转后缀表达式

所谓的中缀表达式其实就是我们平时写的例如:3+4\times (2+ 2)+2\div 2;而它的后缀表达式(也成为逆波兰表达式) 3\; 4\; 2\; 2+ \times + 2\; 2 \;\div +

后缀表达式:指的是不包含括号运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行不再考虑运算符的优先规则)。

我们如果要利用程序来进行四则混合运算最重要的就是将输入的中缀表达式转后缀表达式

首先我们假设运算符中只有 加 减 乘 除 和 括号不然的话程序太复杂了(其实是我不会写【哭】)。

图解

代码实现过程:

首先我们先写一个方法 返回值是动态字符串数组(为了后面好计算),形参为字符串类型(因为输入值不只有数字还有运算符)。这里会用到栈所以也定义一个栈。

    public ArrayList<String> midChangeEng(String str) {
        //这里用动态数组就不用担心不够用
        ArrayList<String> ret = new ArrayList<String>();
        Stack<Character> stack = new Stack<>();
    }

此时再创建一个新方法用来判断传入字符是不是运算符 

    public boolean isOperator(char s) {
        if (s == '+' || s == '-' || s == '*' || s == '/' || s == '(' || s == ')') {
            return true;
        }
        return false;
    }

我们再利用运算符再ASCII码中的位置,创建一个数组用来表示它们的优先级

int[] able = {1,0,0,0,0,1};//分别代表 * + (null) - (null) / 的优先级 

 利用循环遍历字符串

        //遍历字符串
        for (int i = 0; i < str.length(); i++) {
            char a = str.charAt(i);
            String tmp = "";//用来暂时存储出栈的数字
            if (isOperator(a)) {
                //是操作数
            }else{
                //如果是数字就放到ret中
            }
        }

        return ret;

对操作数的操作 ,可是此段代码中重复代码过多,所以可以将其封装成一个方法。

            if (isOperator(a)) {
                //是操作数
                switch (a) {
                    case '+'://判断如果优先级不大于栈顶的元素那么就先出栈在入栈
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '-':
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '*':
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '/':
                        if(!stack.isEmpty()) {//出栈
                            while(!stack.isEmpty() && stack.peek() != '(' && able[(int)stack.peek() - 42] >= able[(int)a-42]) {
                                String b = "";
                                b += stack.pop();
                                ret.add(b);
                            }
                        }
                        stack.push(a);
                        break;
                    case '(':
                        stack.push(a);
                        break;
                    case ')':
                        while(!stack.isEmpty() && stack.peek() != '(') {
                            String b = "";
                            b += stack.pop();
                            ret.add(b);
                        }
                        stack.pop();//删除‘(’
                        break;
                }

            }

 如果是数字就进行以下操作

            else{
                //如果是数字就放到ret中
                String tmp = "";
                while(i < str.length() && !isOperator(str.charAt(i))) {//数字有可能是多位的
                    tmp += str.charAt(i);
                    i++;
                }
                i--;
                ret.add(tmp);
            }

再出函数之前要先将栈里面的全部导出来

        //将栈里面剩余的全部出栈
        while(!stack.isEmpty()) {
            String b = "";
            b += stack.pop();
            ret.add(b);
        }
        return ret;

完整代码: 

    public static ArrayList<String> midChangeEng(String str) {
        //这里用动态数组就不用担心不够用
        ArrayList<String> ret = new ArrayList<String>();
        Stack<Character> stack = new Stack<>();

        int[] able = {1,0,0,0,0,1};//分别代表 * + (null) - (null) / 的优先级
        //遍历字符串
        for (int i = 0; i < str.length(); i++) {
            char a = str.charAt(i);

            if (isOperator(a)) {
                //是操作数
                switch (a) {
                    case '+'://判断如果优先级不大于栈顶的元素那么就先出栈在入栈
                        abcd(ret, stack, able, a);
                        break;
                    case '-':
                        abcd(ret, stack, able, a);
                        break;
                    case '*':
                        abcd(ret, stack, able, a);
                        break;
                    case '/':
                        abcd(ret, stack, able, a);
                        break;
                    case '(':
                        stack.push(a);
                        break;
                    case ')':
                        while(!stack.isEmpty() && stack.peek() != '(') {
                            String b = "";
                            b += stack.pop();
                            ret.add(b);
                        }
                        stack.pop();//删除‘(’
                        break;
                }
            }else{
                //如果是数字就放到ret中
                String tmp = "";
                while(i < str.length() && !isOperator(str.charAt(i))) {//数字有可能是多位的
                    tmp += str.charAt(i);
                    i++;
                }
                i--;
                ret.add(tmp);
            }
        }
        //将栈里面剩余的全部出栈
        while(!stack.isEmpty()) {
            String b = "";
            b += stack.pop();
            ret.add(b);
        }
        return ret;
    }

利用后缀表达式求值:

这部分比较简单所以就直接展示了

完整代码:

        public int evalRPN(String[] tokens) {
            Stack<Integer> stack = new Stack<>();
            for (int i = 0; i < tokens.length; i++) {
                if (isOperator(tokens[i])) {
                    int num2 = stack.pop();
                    int num1 = stack.pop();
                    switch(tokens[i].charAt(0)) {
                        case '+':
                            stack.push(num1 + num2);
                            break;
                        case '-':
                            stack.push(num1 - num2);
                            break;
                        case '*':
                            stack.push(num1 * num2);
                            break;
                        case '/':
                            stack.push(num1 / num2);
                            break;
                    }
                }else {
                    stack.push(Integer.parseInt(tokens[i]));
                }
            }
            return stack.pop();
        }


        public boolean isOperator(String str) {
            if (str.length() != 1) {
                return false;
            }
            if (str.charAt(0) == '+' || str.charAt(0) == '-' || str.charAt(0) == '*' || str.charAt(0) == '/') {
                return true;
            }
            return false;
        }

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

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

相关文章

基于SpringBoot的墙绘产品展示交易平台设计与实现

目录 前言 一、技术栈 二、系统功能介绍 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本墙绘产…

生活垃圾数据集(YOLO版)

文章目录 1、数据集介绍1.1、数据集图片组成2.1、获取数据集方式 2、扩展代码2.1、文件结构树2.2、划分数据集2.3、获取数据集文件名字2.4、文件成功对应检测 3、其他文章 1、数据集介绍 1.1、数据集图片组成 【有害垃圾】&#xff1a;电池&#xff08;1 号、2 号、5 号&…

TensorFlow安装 ,在原本的虚拟环境下配置Tensorflow.

1.TensorFlow安装 &#xff0c;在原本的虚拟环境下配置Tensorflowh和pytorch 2.我首先在anaconda的环境下创建了一个tensorflow文件夹 如何先进入D盘&#xff0c;再进入tensorflow文件夹的目录D:cd D:\Anaconda\TensorFlowSoftWarepip install tensorflow如图所示报错解决方法 …

软件设计师考试学习2

数据结构与算法基础 数组 稀疏矩阵 用代入法计算&#xff0c;A 数据结构的定义 非线性结构分为树和图&#xff0c;区别在于有没有环路 顺序表与链表 引入头节点可以使所有的节点处理方式一致 如果没有空的头节点&#xff0c;头节点需要单独处理 顺序存储与链式存储 查找…

文件操作(2)

目录 文件操作的步骤&#xff1a; 流&#xff1a; 标准流&#xff1a; 文件指针&#xff1a; 文件信息区&#xff1a; 概念&#xff1a; 关系转化&#xff1a; 注意&#xff1a; 文件指针&#xff1a; 文件的打开和关闭&#xff1a; 打开方式&#xff1a; 打开成…

虹科方案 | LIN/CAN总线汽车零部件测试方案

文章目录 摘要一、汽车零部件测试的重要性&#xff1f;二、虹科的测试仿真工具如何在汽车零部件测试展露头角&#xff1f;三、应用场景**应用场景1&#xff1a;方向盘开关的功能测试****应用场景2&#xff1a;各类型电机的控制测试****应用场景3&#xff1a;RGB氛围灯的功能测试…

基于STM32+华为云IOT设计的智能门禁系统

一、项目介绍 智能门禁系统是一种应用物联网技术的智能化安防系统&#xff0c;提供安全高效的门禁管理和远程监控功能。传统的门禁系统通常使用磁卡、密码或钥匙等方式进行开锁&#xff0c;但存在易丢失、易复制、操作繁琐等问题。为了解决这些问题&#xff0c;并提高门禁安全…

postman-pre-request-scripts使用

一、场景 二、定义模拟接口 using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using SaaS.Framework.DataTransfer; using System.Threading.Tasks;namespace SaaS.KDemo.Api.Controllers {[Route("api/[co…

引领初创企业的数字化转型:选择适合的低代码平台

初创企业在初期各项架构都还不完善&#xff0c;对于应用程序的需求多样&#xff0c;但是又要考量成本。所以&#xff0c;低代码平台就是在综合考量成本和需求的情况下的一个突出的选择。下面我们就六个方面为您介绍&#xff1a;初创企业选择的Zoho Creator低代码平台。 1、功能…

PREEvision Client 10.8.0

PREEvision Client 10.6.0 2692407267qq.com&#xff0c;更多内容请见http://user.qzone.qq.com/2692407267/

php代码审计篇熊海cms代码审计

文章目录 自动审计逐个分析首页index.php文件包含漏洞后台逻辑漏洞cookie绕过登录后台sql报错注入存储型XSS 结束吧 自动审计 看到有很多 逐个分析 首页index.php文件包含漏洞 读一下代码&#xff0c;可以看到很明显的一个文件包含 <?php //单一入口模式 error_repor…

(1) ESP32获取图像,并通过电脑端服务器显示图像

目录​​​​​​​ 一、所需器件工具 二、客户端与服务器进行UDP通信 1、客户端代码 2、服务器端代码 3、效果展示 三、客户端拍照&#xff0c;通过UDP传输到服务器进行显示 1、客户端获取图像并UDP传输 2、电脑端服务器显示图像 3、效果展示 四、代码链接 一、所需器…

高压放大器电源有什么作用和用途

高压放大器是一种专门用于放大高压信号的电子设备。它可以将低幅度的输入信号放大成高幅度的输出信号&#xff0c;用于驱动高压负载或处理高压信号。然而&#xff0c;高压放大器需要特定的电能来运行&#xff0c;而这就是电源的作用。 高压放大器电源的主要作用是为高压放大器提…

Python入门教程 | Python 命名空间和作用域

命名空间 先看看官方文档的一段话&#xff1a; A namespace is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries。 中文翻译&#xff1a;命名空间(Namespace)是从名称到对象的映射&#xff0c;大部分的命名空间都是通过 P…

投资理财五大定律

大家好&#xff0c;我是财富智星&#xff0c;今天跟大家分享一下理财的五大定律&#xff0c;一起来学习吧。 一、投资理财&#xff0c;别把鸡蛋放一个篮子里 投资理财&#xff0c;不要把所有的资金都放在同一个理财产品中。应该了解市场上各种理财产品的风险、收益、周期和起买…

古代有没有电子元器件?

手机&#xff0c;电脑&#xff0c;电视等等电子产品&#xff0c;无时无刻充斥在我们的生活中&#xff0c;如果有一天突然没有了这些功能多样的电子产品&#xff0c;估计大部分人都会一时之间难以适应。 这就好比正在上网&#xff0c;结果突然被人断了网&#xff0c;导致无网络连…

Linux实现HTTP服务器

在Linux系统中&#xff0c;我们可以利用HTTP服务器代理来实现网络请求的转发和加速&#xff0c;从而提高网站的访问速度和性能。本文将为您详细介绍如何搭建HTTP服务器代理&#xff0c;让您在网络世界中畅通无阻&#xff0c;更加快速高效地进行数据通信。 一、了解HTTP服务器代…

下载水果FLStudio21.2软件安装更新教程

编曲是一种对音乐创作过程中涉及的元素和步骤进行组织和安排的艺术形式。对于想要学习编曲的人来说&#xff0c;以下是一些有用的建议&#xff1a; 1. 学习基础知识 在开始学习编曲之前&#xff0c;你需要掌握一些基础知识&#xff0c;例如音乐理论、乐器演奏和数字音乐制作技…

【Elsevier旗下】JCR2/3区,最快25天录用!计算机与娱乐、教育、游戏、新媒体均可

期刊简介&#xff1a; 出版社&#xff1a;Elsevier 影响因子&#xff08;2022&#xff09;&#xff1a;2.5-3.0 期刊分区&#xff1a;JCR2/3区&#xff0c;中科院4区 检索数据库&#xff1a;SCIE 在检 数据库检索年份&#xff1a;2016年 预警情况&#xff1a;无中科院预警…

【计算机毕业设计】基于SpringBoot的电影在线预定与管理系统的设计与实现

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…