逆波兰计算器的完整代码

news2024/11/24 15:59:59

前置知识:

 

 

将中缀表达式转为List方法:

 //将一个中缀表达式转成中缀表达式的List
    //即:(30+42)*5-6 ==》[(, 30, +, 42, ), *, 5, -, 6]
    public static List<String> toIndixExpressionList(String s) {
        //定义一个List,存放中缀表达式对应的内容
        List<String> ls = new ArrayList<String>();
        int i = 0; //这是一个指针,用于遍历 中缀表达式字符串
        String str = ""; //对多位数的拼接
        char c; //每遍历到一个字符,我需要加入到ls
        do {
            //如果是一个字符,直接添加到list
            if ((c = s.charAt(i)) < '0' || (c = s.charAt(i)) > '9') {
                ls.add("" + c);
                i++; //指针后移
            } else { //如果是一个数,需要考虑多位数
                str = ""; //将字符串置空
                while ((i < s.length()) && (c = s.charAt(i)) >= '0' && (c = s.charAt(i)) <= '9') {
                    str += c;
                    i++;
                }
                ls.add(str);
            }
        } while (i < s.length());
        return ls;
    }

将中缀表达式转化为后缀表达式(删除小括号):
 

 //将得到的中缀表达式对应的 List => 后缀表达式对应的 List
    // [(, 30, +, 42, ), *, 5, -, 6] ==》 30,42,+,5,*,6,-
    public static List<String> parseSuffixExpressionList(List<String> ls){
        //定义两个栈
        Stack<String> operStack = new Stack<String>();   //符号栈
        //因为 resStack ,这个栈整个转换过程中,没有pop操作,而且后面我们还需要逆序输出
        //因此我们这里使用 List<String> resList作为结果的存储
        List<String> resList = new ArrayList<String>();

        //遍历ls
        for (String item :ls) {
            //如果是一个数就直接加入到resList
            if(item.matches("\\d+")){
                resList.add(item);
            }else if (item.equals("(")){
                 operStack.push(item);
            }else if(item.equals(")")){
                //如果是右括号,则依次弹出 operStack 栈顶的运算符,并压入s2,
                // 直到遇到左括号为止,此时将这一对括号丢弃
                while (!operStack.peek().equals("(")) {
                    String temp = operStack.pop();
                    resList.add(temp);
                }
                    operStack.pop(); //将 ( 弹出符号栈,消除小括号
            }else {
                //当item的优先级 <= operStack 栈顶运算符,
                // 将 operStack 栈顶的运算符弹出并加入到 resList中
                // 再次与新 operStack 中新的栈运算符相比较
                while (operStack.size() != 0 && Operation.getValue(operStack.peek()) >= Operation.getValue(item)){
                    resList.add(operStack.pop());
                }
                //还需要将item压入栈中
                operStack.push(item);
            }
        }
        //将operStack中剩余的运算符依次弹出并加入到resList中
        while (operStack.size()!=0){
            resList.add(operStack.pop());
        }
        return resList; //注意因为是存放到List,因此按顺序输出就是对应的后缀表达式
    }

运算符的优先级:

//编写一个类 Operation 可以返回一个运算符 ,对应的优先级
class Operation{
    private static int ADD = 1;
    private static int SUB = 1;
    private static int MUL = 2;
    private static int DIV = 2;

    //写一个方法,返回对应的优先级数字
    public static int getValue(String operation){
        int result = 0;
        switch (operation){
            case "+":
                result = ADD;
                break;
            case "-":
                result = SUB;
            break;
            case "*":
                result = MUL;
            break;
            case "/":
                result = DIV;
            break;
            default:
                System.out.println("不存在该运算符~");
                break;
        }
        return result;
    }
}

 运算方法:

    public static int cal(List<String> list) {
        //创建一个栈
        Stack<String> stack = new Stack<String>();
        int res = 0;
        //遍历 list
        for (String s : list) {
            //这里使用正则表达式取出来数
            if (s.matches("\\d+")) {//如果是多个数字,直接入栈
                stack.push(s);
            } else {
                //如果取出的不是数字,需要弹出两个数字,进行运算,将运算结果,继续入栈操作
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                if (s.equals("+")) {
                    res = num1 + num2;
                } else if (s.equals("-")) {
                    res = num1 - num2;
                } else if (s.equals("*")) {
                    res = num1 * num2;
                } else if (s.equals("/")) {
                    res = num1 / num2;
                } else {
                    throw new RuntimeException("您输入的运算符有误!");
                }
                stack.push("" + res);
            }
        }
        return Integer.parseInt(stack.pop());
    }

测试类:

public static void main(String[] args) {
        //先定义逆波兰表达式
        //(3+4)*5-6 ==> 3 4 + 5 * 6 -
        //说明为了方便,逆波兰表达式的 数字和字符使用空格隔开
        String Expression = "(10+2)*5-6*2";

        /** 思路
         *  1. 先将 " 3 4 + 5 * 6 - " => 放到ArrayList中
         *  2. 将ArrayList 传递给一个方法,遍历ArrayList 配合栈 完成计算
         */

        //得到一个后缀表达式
        List<String> list = toIndixExpressionList(Expression);

        System.out.println("运算表达式为:" + list);

        //将中缀表达式转化为后缀表达式
        List<String> suffixExpression = parseSuffixExpressionList(list);
        System.out.println("后缀表达式为: "+suffixExpression);


        //现在进行运算
        System.out.println(list + " = " + cal(suffixExpression));
    }

 控制台输出:

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

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

相关文章

[Unity]接入Firebase 并且关联支付埋点

首先 在这个下一下FireBase的资源 firebase11.0.6 然后导入Analytics Auth Crashlytics 其他的看着加就行 然后直接丢到Unity里面 接下来需要去Firebase里面下载 Google json 丢到 这个下面 然后就是脚本代码了 using System.Collections; using System.Collection…

html/css实现简易圣诞贺卡

一、前言 HTML&#xff0c;全称HyperText Markup Language&#xff0c;即超文本标记语言&#xff0c;是用于创建网页的标准标记语言。HTML是一种标记语言&#xff0c;由一系列的元素标签组成&#xff0c;用于描述网页的结构和内容。 CSS&#xff0c;全称是“层叠样式表”&#…

音视频的编码格式与封装格式

音视频的编码格式与封装格式是两个不同的概念&#xff0c;视频封装格式常见的有&#xff1a;mp4&#xff0c;rmvb&#xff0c;avi&#xff0c;mkv&#xff0c;mov&#xff0c;mpg&#xff0c;vob&#xff0c;3gp&#xff0c;asf&#xff0c;rmvb&#xff0c;wmv&#xff0c;div…

中伟视界:天然气站安全隐患AI解决方案, 人工智能, 安全风险评估, 预测维护, 智能管理

近年来&#xff0c;随着人工智能技术的不断发展&#xff0c;越来越多的行业开始将人工智能应用于生产和管理中。在天然气行业&#xff0c;利用人工智能AI算法排除安全隐患已经成为一种新的趋势。那么&#xff0c;天然气站如何利用人工智能AI算法排除安全隐患呢&#xff1f;接下…

15、Qt显示图片并支持缩放、移动等操作

一、新建项目 点击“New Project”&#xff0c;选择“Application”“Qt Widget Application”&#xff0c;点击“Choose” 更改项目名称和位置 选择编译器 默认 默认 二、创建自定义类 右击项目名&#xff0c;选择“Add New” 选择“C” -> "C Class"&#xff…

数据结构和算法-二叉排序树(定义 查找 插入 删除 时间复杂度)

文章目录 二叉排序树总览二叉排序树的定义二叉排序树的查找二叉排序树的插入二叉排序树的构造二叉排序树的删除删除的是叶子节点删除的是只有左子树或者只有右子树的节点删除的是有左子树和右子树的节点 查找效率分析查找成功查找失败 小结 二叉排序树 总览 二叉排序树的定义 …

7-1 建立二叉搜索树并查找父结点(PTA - 数据结构)

按输入顺序建立二叉搜索树&#xff0c;并搜索某一结点&#xff0c;输出其父结点。 输入格式: 输入有三行&#xff1a; 第一行是n值&#xff0c;表示有n个结点&#xff1b; 第二行有n个整数&#xff0c;分别代表n个结点的数据值&#xff1b; 第三行是x&#xff0c;表示要搜索值…

华清远见作业第十四天

思维导图 1、顺序表按元素删除 代码&#xff1a; int delete_num_delete(sqlist *list,datatype key) {int indexseek_num(list,key);//元素查找函数if(index-1){return -1;}delete_index(list,index);return 0; } 2、顺序表按照元素修改 代码&#xff1a; //顺序表按照元…

人流量监测识别摄像机

人流量监测识别摄像机是一种基于人工智能技术的智能监控设备&#xff0c;其主要功能是通过摄像头捕捉实时画面&#xff0c;利用深度学习算法对画面中的人数进行实时识别和统计。这种摄像机可以广泛应用于各种场合&#xff0c;如商场、车站、学校、医院等公共场所&#xff0c;以…

Transformer引领AI领域:从模型到平台,全方位探索与实践

编辑推荐 在不到4 年的时间里&#xff0c;Transformer 模型以其强大的性能和创新的思想&#xff0c;迅速在NLP 社区崭露头角&#xff0c;打破了过去30 年的记录。BERT、T5 和GPT 等模型现在已成为计算机视觉、语音识别、翻译、蛋白质测序、编码等各个领域中新应用的基础构件。…

es、MySQL 深度分页问题

文章目录 es 深度分页MySQL 深度分页 es 深度分页 es 深度分页问题&#xff0c;有点忘记了&#xff0c;这里记录一下 当索引库中有10w条数据&#xff0c;比如是商品数据&#xff1b;用户就是要查在1w到后10条数据&#xff0c;怎么查询。 es查询是从各个分片中取出前1w到后10条数…

redis 从0到1完整学习 (五):集合 IntSet 数据结构

文章目录 1. 引言2. redis 源码下载3. IntSet 数据结构4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&#xff09;&#xff1a;redis 常用命令》 《redi…

JavaOOP篇----第十篇

系列文章目录 文章目录 系列文章目录前言一、构造方法能不能显式调用?二、什么是方法重载?三、构造方法能不能重写?能不能重载?四、内部类与静态内部类的区别?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,…

Springboot启动异常 OgnlException: sqlSelect [java.lang.NoSuchMethodError

完整的日志如下&#xff1a; Invocation of init method failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression ew ! null and ew.sqlSelect ! null. Cause…

协作机器人(Collaborative-Robot)安全碰撞的速度与接触力

协作机器人&#xff08;Collaborative-Robot&#xff09;的安全碰撞速度和接触力是一个非常重要的安全指标。在设计和使用协作机器人时&#xff0c;必须确保其与人类或其他物体的碰撞不会对人员造成伤害。 对于协作机器人的安全碰撞速度&#xff0c;一般会设定一个上限值&…

Excel排序怎么做?记好这些正确操作!

“我是个职场新手&#xff0c;对excel的使用还不是很熟悉。但是我需要处理一份文件。有朋友可以简单介绍一下excel排序的操作方法吗&#xff1f;” Excel作为一个实用的办公工具&#xff0c;给用户带来了很多的方便。在使用excel时&#xff0c;排序功能是比较重要且常用的。我们…

轴承故障诊断分类模型全家桶-最全教程

Python轴承故障诊断 (一)短时傅里叶变换STFT-CSDN博客 Python轴承故障诊断 (二)连续小波变换CWT-CSDN博客 Python轴承故障诊断 (三)经验模态分解EMD-CSDN博客 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Trans…

打造明厨亮灶工程,需要哪些AI视频智能算法助力?

旭帆科技AI智能监控可以通过摄像头、传感器和数据处理等技术手段&#xff0c;实时监测厨房人员着装、行为与烟火等&#xff0c;对厨房实时监控进行分析与记录&#xff0c;从而实现明厨亮灶场景的搭建&#xff0c;保障食品安全和服务质量。 1、烟火识别 对于后厨来说&#xff0…

搭建动态网站之——基于Redhat8.6搭建Discuz论坛

目录 一、动态网站与静态网站区别 1、提供用户互动接口的动态网站 2、搭建动态网站的需求&#xff1a; 二、搭建步骤 第一步&#xff1a;www服务器配置 第二步;编辑网页文件 第三步&#xff1a;使用xftp 将Discuz包传到/discuz解压 1、将Discuz包移动到/discuz 2、解压…

双燃料发动机,预计2025年市场规模将达到39亿美元

双燃料发动机是一种可以使用两种不同类型的燃料&#xff08;通常是天然气和柴油&#xff09;运行的发动机&#xff0c;具有更大的灵活性和更低的排放。近年来&#xff0c;在对更清洁、更高效能源的需求不断增长的推动下&#xff0c;双燃料发动机市场增长迅速。 全球市场&#x…