数据结构-栈和队列刷题集(长期更新)

news2024/11/27 8:42:48

文章目录

      • 万能计算器的实现以及源码分析
      • 1. leetcode 150 逆波兰表达式求值

万能计算器的实现以及源码分析

/**
 * 我们尝试写一个完整版的计算器,由于计算机不能很好的识别括号,所以一般要转换为逆波兰表达式求解
 * 思路解析 :
 * 1. 输入一个 中缀表达式
 * 2. 中缀表达式转化为list存储
 * 3. 把list转换为一个逆波兰表达式
 *      规则如下 首先准备两个栈,stack1 , list2(stack2)
 *      如果是数字直接装入 list2
 *      如果是括号 分为左括号跟右括号
 *         如果是左括号直接进入stack1
 *         如果是右括号 stack1 弹栈 ,弹出的元素进入stack2,直到出现 ')' ,抵消掉一个右括号
 *      如果是操作符
 *          如果stack1 为空 或者是 栈顶为左括号,那么直接入栈          <---------------------------
 *          如果操作符的优先级大于 栈顶 操作符的优先级,直接入栈                                    *
 *          如果操作符的优先级小于等于 栈顶操作符 ,那么就弹出栈顶元素入stack2,然后进入第一条比较 --------
 *
 * 4. 利用逆波兰表达式进行求值
 */
class MyCalculator{
    public static void main(String[] args) {
        String s = "1+ ((2 +3) *4 )-5";
        List<String> infixexperssion = toList(s);
        List<String> suffixexpression = toSuffixexpression(infixexperssion);
        int ret = calculate(suffixexpression);
        System.out.println(ret);
    }

    /**
     * 该方法的作用就是把一个字符串转换为一个中缀表达式的list
     * @param infixexpression : 中缀表达式
     * @return
     */
    public static List<String> toList(String infixexpression){
        List<String> ret = new ArrayList<>();
        int count = 0;
        while(count < infixexpression.length()){
            if(infixexpression.charAt(count) == ' '){
                count++;
                continue;
            }
            if(infixexpression.charAt(count) < '0' || infixexpression.charAt(count) > '9'
                    && infixexpression.charAt(count)!=' '){
                ret.add(infixexpression.charAt(count) + "");
                count++;
            }else{
                StringBuilder stringBuilder = new StringBuilder();
                while(count < infixexpression.length() && infixexpression.charAt(count)>='0'
                        && infixexpression.charAt(count)<='9'){
                    stringBuilder.append(infixexpression.charAt(count));
                    count++;
                }
                ret.add(stringBuilder.toString());
            }
        }
        return ret;
    }


    /**
     * 该方法的作用是将我们的中缀表达式转化为逆波兰表达式
     * @param infixexpression : 传入的中缀表达式
     * @return
     */
    public static List<String> toSuffixexpression(List<String> infixexpression){
        //首先创建两个栈,因为第二个栈不涉及弹栈操作,所以我们可以创建为顺序表
        Stack<String> stack = new Stack<>();
        List<String> list = new ArrayList<>();

        for(String elem : infixexpression){
            if(elem.equals("(")){
                stack.push(elem);
            }else if(elem.equals(")")){
                while(stack.size() != 0 && !stack.peek().equals("(")){
                    list.add(stack.pop());
                }
                stack.pop();
            }else if(isOperator(elem) ){
                if(stack.size() == 0 || stack.peek().equals("(") || priority(elem) > priority(stack.peek())){
                    stack.push(elem);
                    continue;
                }
                while(stack.size() != 0 && priority(elem) <= priority(stack.peek()) && !stack.peek().equals("(")){
                    list.add(stack.pop());
                }
                stack.push(elem);
            }else{
                list.add(elem);
            }
        }
        while(stack.size() != 0){
            list.add(stack.pop());
        }
        return list;
    }

    //判断是否是操作符
    public static boolean isOperator(String elem){
        if(elem.equals("+")||elem.equals("-")||elem.equals("*")||elem.equals("/")){
            return true;
        }
        return false;
    }

    //判断优先级的大小
    public static int priority(String elem){
        if(elem.equals("+") || elem.equals("-")){
            return 1;
        }else{
            return 2;
        }
    }

    /**
     * 最后收一下尾巴,用我们所得到的逆波兰表达式求出值
     * 求值的基本思路应该比较好理解
     * 如果是数字直接入栈,如果不是,弹出两个数字,然后进行运算结果入栈
     */
    public static int calculate(List<String> sufferixexperssion){
        Stack<String> stack = new Stack<>();
        for(String elem : sufferixexperssion){
            if(isOperator(elem)){
                int num2 = Integer.parseInt(stack.pop());
                int num1 = Integer.parseInt(stack.pop());
                switch (elem){
                    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(elem);
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

1. leetcode 150 逆波兰表达式求值

逆波兰表达式又叫做后缀表达式,因为计算机是好辨认出中缀表达式的计算顺序的,所以有时候要用后缀表达式进行求解
题目描述
在这里插入图片描述
思路分析:
1.如果是数字,直接入栈
2.如果是操作符,弹出两个数字分别作为右操作数跟左操作数运算,结果入栈
3.最后弹出栈内的最后一个元素
代码实现如下

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

    //判断是不是操作符
    public static boolean toolOperator(String s) {
        if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {
            return true;
        }
        return false;
    }

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

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

相关文章

鸡汤笔记-致自己

《你只是看起来很努力》李尚龙 我们看起来每天熬夜&#xff0c;却只是拿着手机点了无数个赞&#xff1b;看起来在图书馆坐了一天&#xff0c;却真的只是坐了一天&#xff1b;看起来买了很多书&#xff0c;只不过晒了个朋友圈&#xff1b;看起来每天很晚地离开办公室&am…

聊聊go语言中的内存填充

写在文章开头 我们都知道数据加载到CPU缓存中可以提升执行性能&#xff0c;所以为了保证每一个结构体中的成员能够完整的被单个CPU核心加载以避免缓存一致性问题而提出内存对齐&#xff0c;这篇文章笔者会从go语言的角度来讨论这个优化机制。 Hi&#xff0c;我是 sharkChili &…

基于Springboot+Vue的Java项目-网上点餐系统开发实战(附演示视频+源码+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &am…

杀鸡焉用牛刀,用unity3D开发数字孪生是大材小用吗?

"杀鸡焉用牛刀"这句话的意思是指使用过于强大或不适合的工具来完成一个简单的任务。而用Unity3D开发数字孪生并不一定是大材小用。 Unity3D是一款功能强大的游戏开发引擎&#xff0c;它可以用于开发各种类型的游戏和交互应用程序。数字孪生是一种基于现实世界对象的虚…

网络靶场实战-PE 自注入

默认的 Windows API 函数&#xff08;LoadLibrary、LoadLibraryEx&#xff09;只能加载文件系统中的外部库&#xff0c;无法直接从内存中加载 DLL&#xff0c;并且无法正确地加载 EXE。有时候&#xff0c;确实需要这种功能&#xff08;例如&#xff0c;不想分发大量文件或者想增…

Redis入门到通关之解决Redis缓存一致性问题

文章目录 ☃️概述☃️数据库和缓存不一致采用什么方案☃️代码实现☃️其他 ☃️概述 由于我们的 缓存的数据源来自于数据库, 而数据库的 数据是会发生变化的, 因此,如果当数据库中 数据发生变化,而缓存却没有同步, 此时就会有 一致性问题存在, 其后果是: 用户使用缓存中的过…

Python 数据结构和算法实用指南(二)

原文&#xff1a;zh.annas-archive.org/md5/66ae3d5970b9b38c5ad770b42fec806d 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第四章&#xff1a;列表和指针结构 我们已经在 Python 中讨论了列表&#xff0c;它们方便而强大。通常情况下&#xff0c;我们使用 Python…

【C语言__基础概念__复习篇8】

目录 前言 一、C语言是什么 二、C语言的发展历史 三、编译器的选择 3.1 编译和链接 3.2 编译器的对比 3.3 VS如何使用 四、main函数 五、关键字 六、字符和ASCII编码 七、字符串和\0 八、转义字符 九、注释 十、数据类型 10.1 数据类型的介绍 10.2 数据类型大小的计…

有哪些网站设计教程

网站设计教程是帮助人们学习如何设计和开发网站的资源&#xff0c;它们提供了从基础知识到高级技巧的全方位指导。无论您是初学者还是经验丰富的开发者&#xff0c;都可以从这些教程中获益。下面是一些广受欢迎的网站设计教程&#xff0c;它们涵盖了各种技术和工具&#xff1a;…

Linux之进程控制进程终止进程等待进程的程序替换替换函数实现简易shell

文章目录 一、进程创建1.1 fork的使用 二、进程终止2.1 终止是在做什么&#xff1f;2.2 终止的3种情况&&退出码的理解2.3 进程常见退出方法 三、进程等待3.1 为什么要进行进程等待&#xff1f;3.2 取子进程退出信息status3.3 宏WIFEXITED和WEXITSTATUS&#xff08;获取…

【C++题解】1345. 玫瑰花圃

问题&#xff1a;1345. 玫瑰花圃 类型&#xff1a;基本运算、小数运算 题目描述&#xff1a; 有一块nn&#xff08;n≥5&#xff0c;且 n 是奇数&#xff09;的红玫瑰花圃&#xff0c;由 nn 个小正方形花圃组成&#xff0c;现要求在花圃中最中间的一行、最中间的一列以及 4 个…

SpringBoot多数据源基于mybatis插件(三)

SpringBoot多数据源基于mybatis插件&#xff08;三&#xff09; 1.主要思路2.具体实现 1.主要思路 MyBatis的插件机制允许你在MyBatis的四大对象&#xff08;Executor、StatementHandler、ParameterHandler和ResultSetHandler&#xff09;的方法执行前后进行拦截&#xff0c;并…

考察自动化立体库应注意的几点

导语 大家好&#xff0c;我是智能仓储物流技术研习社的社长&#xff0c;老K。专注分享智能仓储物流技术、智能制造等内容。 整版PPT和更多学习资料&#xff0c;请球友到知识星球 【智能仓储物流技术研习社】自行下载 考察自动化立体仓库的关键因素&#xff1a; 仓库容量&#x…

linux 中ifconfig 无法使用

1、先看问题 2、搜索 ifconfig 命令&#xff0c;看下该命令在哪 yum search ifconfig 可以看到ifconfig命令在 net-tools.x86_64这个包里。 3、下面开始安装&#xff0c;执行下面的命令 yum install net-tools.x86_64 4、查看是否安装成功 ifconfig 看到上面的ip就说明可以用了…

光网络中的低偏SOA与无源波导单片集成

----翻译自Aref Rasoulzadeh Zali等人2021年撰写的文章 摘要 在光通信系统中&#xff0c;非常需要可以通过简单工艺与无源光路单片集成的低偏振相关半导体光放大器&#xff08;SOA&#xff09;。然而&#xff0c;尽管已经报道了几种SOA&#xff0c;但在InP平台中将偏振无关的体…

ROS学习笔记(12)AEB和TTC的实现

0.前提 在自动驾驶领域有许多关于驾驶安全的措施AEB和TTC就是为了驾驶安全而设计出来的。在这篇文章中我会讲解我对AEB和TTC算法的一些理解。本期ROS学习笔记同时也是ros竞速小车的学习笔记&#xff0c;我会将我的部分代码拿出来进行讲解&#xff0c;让大家更好的理解ttc和aeb…

html接入高德地图

1.申请key key申请地址&#xff1a;https://console.amap.com/dev/key/app 官方文档 https://lbs.amap.com/api/javascript-api-v2/summary 2.html接入示例 需要将YOUR_KEY替换成自己的key <!doctype html> <html> <head><meta charset"utf-…

未来计算机的发展趋势是什么?

未来计算机的发展趋势是多方面的,涵盖了硬件、软件、体系结构以及计算范式等多个层面。以下是一些预期的趋势: 1. 量子计算: 随着量子理论的不断成熟和技术的进步,量子计算机将可能解决传统计算机难以处理的问题,比如药物发现、材料科学、复杂系统模拟等领域。量子计算的…

VMWare Ubuntu压缩虚拟磁盘

VMWare中ubuntu会越用越大&#xff0c;直到占满预分配的空间 即使系统里没有那么多东西 命令清理 开机->open Terminal sudo vmware-toolbox-cmd disk shrink /关机-> 编辑虚拟机设置->硬盘->碎片整理&压缩 磁盘应用 开机->disk usage analyzer(应用) …

Java面试:算法常用面试题汇总

1.说一下什么是二分法&#xff1f;使用二分法时需要注意什么&#xff1f;如何用代码实现&#xff1f; 二分法查找&#xff08;Binary Search&#xff09;也称折半查找&#xff0c;是指当每次查询时&#xff0c;将数据分为前后两部分&#xff0c;再用中值和待搜索的值进行比较&…