iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java怎么用栈实现综合计算器
  • 652
分享到

Java怎么用栈实现综合计算器

2023-07-02 09:07:03 652人浏览 八月长安
摘要

本篇内容介绍了“Java怎么用栈实现综合计算器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!栈栈(stack)又名堆栈,它是一种运算受限的线

本篇内容介绍了“Java怎么用栈实现综合计算器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

栈(stack)又名堆栈,它是一种运算受限的线性表 。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

概念随便一看,反正就是先进后出的一种数据结构,什么是栈这里不做赘述,下面看一下如何在Java中,利用数组实现模拟一个栈。

Java实现栈

可以用数组来简单的模拟出一个栈的结构。

栈一共两个操作,入栈和出栈

我们只需要一个指针指向栈顶即可完成:

出栈的时候将栈顶指针指向的数据取出,指针左移一位指向新的栈顶数据

入栈的时候将栈顶指针后移一位,新的栈顶数据放入指针所在位置

注意:当然,由于数组存储空间是定长的,需要指定栈的大小,出入栈也需要判断栈空、栈满

用类ArrayStack作为栈对象

属性maxSize存放栈的大小,用于判断栈是否满

属性stack[]是用于存放栈的数组

top指针指向栈顶,初始化指向-1(因为入栈要先后移)

方法有——查看栈顶数据、判断栈是否空、判断栈是否满、入栈、出栈、打印栈

代码如下:

class ArrayStack{        private int maxSize;        private int[] stack;        private int top = -1;        public ArrayStack(int maxSize){        this.maxSize = maxSize;        stack = new int[maxSize];    }        public int topData(){        return stack[top];    }        public boolean isFull(){        return top==maxSize-1;    }        public boolean isNull(){        return top==-1;    }        public void push(int data){        //先判断栈是否是满的        if (isFull()){            //如果是满的,打印错误,直接返回            System.out.println("栈已满");            return;        }        //栈没满,入栈        // top++;stack[top]=data;        stack[++top] = data;    }        public int pop(){        //先判断栈是否为空        if (isNull()){            //如果为空,抛出异常            throw new RuntimeException("栈为空,没有可出栈数据");        }        //不为空执行出栈        return stack[top--];    }        public void showStack(){        //先判断是否为空栈        if (isNull()){            System.out.println("栈为空,没有数据");            return;        }        //遍历显示栈        for (int i = top; i >= 0; i--) {            System.out.printf("stack[%d]=%d\n",i,stack[i]);        }    }

至此,一个简单的栈结构就模拟完成了

那么栈可以用来做什么呢?

进制转换、判断括号是否匹配、算数表达式的计算、中缀表达式转换后缀表达式

本文来实现一个中缀表达式的计算、后缀表达式计算以及中缀表达式转换后缀表达式

栈实现综合计算器

首先分析,表达式由运算数和运算符组成,运算符具有优先级问题,所以在计算一个表达式时,是根据运算符优先级顺序对运算数进行对应运算符的计算

那么首先需要一些工具方法对用于遍历表达式时的判断,和运算表达式时的计算

包括:

判断字符是否是一个运算符

判断字符是否是括号

判断运算符的优先级

根据运算符计算两个数据

        static boolean isOperator(int operator){        return operator=='+'||operator=='-'||operator=='*'||operator=='/';    }        static boolean isBracket(int operator){        return operator=='('||operator==')';    }        static int priority(int operator){        if (operator == '+' || operator == '-'){            return 0;        }        if (operator == '*' || operator == '/'){            return 1;        }        return -1;    }        static int calculate(int num1,int num2,int operator){        int res = 0;        switch (operator){            case '+':                res = num2 + num1;                break;            case '-':                res = num2 - num1;                break;            case '*':                res = num2 * num1;                break;            case '/':                res = num2 / num1;                break;            default:                break;        }        return res;    }

1.中缀表达式直接计算

这里实现直接计算一个中缀表达式,没有写入对括号的判断,所以只能是计算最简单的加减乘除

具体实现思路,需要两个栈,一个栈放运算数,一个栈放运算符

遍历整个算数表达式的字符串

会有两种情况,遇到运算符或者遇到运算数

如果遇到运算数就加入到数栈中

如果是运算符需要循环判断符号栈的情况,如果符号栈不为空且当前运算符优先级小于等于栈顶运算符,就弹出两个运算数一个运算符进行计算,计算结果压入数栈;直到符号栈为空或者当前运算符优先级大于栈顶,就将当前运算符入符号栈

算术表达式遍历结束后,继续计算,循环弹出两个数一个符号,计算结果入数栈,直到符号栈为空,此时数栈中剩下一个数字就是表达式的计算结果

        static int calculateMid(String expression) {        //数字栈        ArrayStack numStack = new ArrayStack(10);        //运算符栈        ArrayStack operatorStack = new ArrayStack(10);        //遍历字符串进行入栈等运算操作        for (int i = 0; i < expression.length(); i++) {            //遍历到字符串中的一个字符            char ch = expression.charAt(i);            //判断是否为运算符            if (isOperator(ch)) {                //如果是运算符,判断当前符号栈是否为空                //不为空,判断当前符号优先级和栈中符号优先级的关系进行操作                //当前运算符优先级小于等于栈中运算符优先级,从数栈中pop两个数据,运算符栈中pop一个运算符进行计算,计算结果push进数栈,新运算符再次进行优先级判断                while (!operatorStack.isNull() && priority(ch) <= priority(operatorStack.topData())){                    int num1 = numStack.pop();                    int num2 = numStack.pop();                    int operator = operatorStack.pop();                    int res = calculate(num1, num2, operator);                    numStack.push(res);                }                //直到当前运算符优先级大于栈中运算符优先级或栈为空,再入栈                operatorStack.push(ch);            }else {                //如果不是运算符,判断是否是数字                if (Character.isDigit(ch)) {                    //如果是数字,准备记录下这个数字                    StringBuilder num = new StringBuilder(String.valueOf(ch));                    //找到下一个字符判断,进行拼接操作,直到下一个为运算符或没有下一个字符为止                    while (i+1 < expression.length()&&!isOperator(expression.charAt(i+1))) {                        //如果还是数字,先将数字拼接,再i++                        num.append(expression.charAt(i+1));                        i++;                    }                    numStack.push(Integer.parseInt(num.toString()));                }else {                    //如果不是数字(到这里就既不是数字也不是运算符)报错表达式有误                    throw new RuntimeException("运算表达式有误,不支持的符号:[ "+ch+" ]");                }            }        }        //遍历结束后将栈中继续计算直到数栈中只有一个数字,就是结果        while (!operatorStack.isNull()){            int num1 = numStack.pop();            int num2 = numStack.pop();            int operator = operatorStack.pop();            int res = calculate(num1, num2, operator);            numStack.push(res);        }        return numStack.pop();    }

2.后缀表达式计算

后缀表达式是也称逆波兰表达式,是一种计算机更好处理的表达式结构

因为后缀表达式相当于按照优先级、括号等,排好了计算顺序,计算机只需要顺序向后加载计算即可

用到一个数栈就够了,只需要遍历表达式,遇到数字直接入栈,遇到符号直接出栈两个数字进行运算,将结果再入栈,直到表达式遍历结束,栈中就剩下一个数字就是计算结果

代码如下:

这里将表达式格式限制为每个不同元素用空格隔开,便不需要加载操作数时判断多位数了

        static int calculateSuf(String expression){        //1.将后缀表达式拆开放入集合        String[] expressionList = expression.split(" ");        //2.创建数栈        ArrayStack numStack = new ArrayStack(10);        for (String s : expressionList) {            //判断是否是符号            if (isOperator(s.charAt(0))) {                //是符号就出栈两个数据进行计算                int num1 = numStack.pop();                int num2 = numStack.pop();                int res = calculate(num1, num2, s.charAt(0));                //计算结果入栈                numStack.push(res);            }else {                //不是符号转换为数字入栈即可                int num;                try {                    num = Integer.parseInt(s);                }catch (NumberFORMatException e){                    throw new RuntimeException("错误的表达式:[ "+s+" ]");                }                numStack.push(num);            }        }        return numStack.pop();    }

中缀表达式转后缀表达式

中缀表达式就是生活中使用的算数表达式

比如一个中缀表达式:1+((2+3)*4)-5

转换为后缀表达式为:1 2 3 + 4 * + 5 -

目前,如果要我自己去转换,一般采用树来辅助,更好记忆和理解,将中缀表达式转换成树形结构,再后序遍历这个树就能得到后缀表达式

这个转换过程,用算法来完成,是稍有些复杂的,转换算法也是前人长时间的智慧结晶,没有看到过转换方法之前,自己想不到怎么转换还算蛮正常的,重点体会一下这个思路就好,其实整个思路也是根据之前计算中缀表达式得来

转换算法思路:

初始化两个栈,一个是符号栈s1,一个是中间结果栈s2

从左到右扫描中缀表达式

遇到操作数直接入栈s2

遇到运算符还是循环判断,当运算符栈不为空且当前运算符优先级不大于栈顶运算符时,就弹出一个运算符压入中间结果栈,直到栈为空或当前运算符优先级大于栈顶运算符优先级(这里判断优先级,会出现左括号,左括号当做最低优先级,也就是遇到左括号就直接运算符入栈即可)

遇到括号时,如果是左括号,直接入栈s1;如果是右括号,依次弹出s1中的运算符压入s2,直到遇见左括号为止,此时将一对括号丢弃

直到整个表达式遍历结束,再将s1中剩余的运算符依次弹出压入s2

此时s2栈弹出顺序的逆序就是后缀表达式

代码如下:

    static String infixToSuffix(String infix){        //运算符栈        ArrayStack operatorStack = new ArrayStack(20);        //结果栈        ArrayStack resStack = new ArrayStack(20);        //遍历扫描中缀表达式        for (int i = 0; i < infix.length(); i++) {            //遍历到的一个字符            char ch = infix.charAt(i);            //判断是否为运算符            if (isOperator(ch)){                //循环判断如果运算符栈不为空且当前运算符优先级不大于栈顶运算符                while (!operatorStack.isNull() && priority(ch) <= priority(operatorStack.topData())){                    //弹出运算符栈压入结果栈                    resStack.push(operatorStack.pop());                }                //当前运算符入运算符栈                operatorStack.push(ch);            }            //如果不是运算符再判断是否是运算数,是就直接压入结果栈            else if (Character.isDigit(ch)){                //如果是数字,记录下这个数字压入结果栈                StringBuilder num = new StringBuilder(String.valueOf(ch));                //找到下一个字符判断,进行拼接操作,直到下一个为运算符或没有下一个字符为止                while (i+1 < infix.length()&&Character.isDigit(infix.charAt(i+1))) {                    //如果还是数字,先将数字拼接,再i++                    num.append(infix.charAt(i+1));                    i++;                }                resStack.push(Integer.parseInt(num.toString()));            }            //如果不是运算符也不是操作数,判断是否为括号            else if (isBracket(ch)){                //如果是括号,判断左括号压入运算符栈                if (ch=='('){                    operatorStack.push(ch);                }                //如果是右括号,依次弹出s1的运算符,压入结果栈,直到遇见左括号(丢弃这一对括号)                else if (ch==')'){                    while (true){                        int top = operatorStack.pop();                        if (top=='('){                            break;                        }                        resStack.push(top);                    }                }            }        }        //遍历结束后,将运算符栈中剩余的运算符依次弹出压入结果栈        while (!operatorStack.isNull()){            resStack.push(operatorStack.pop());        }        //遍历结果栈返回后缀表达式字符串(这里是反的)        StringBuilder res = new StringBuilder();        while (!resStack.isNull()){            int pop = resStack.pop();            if (isOperator(pop)){                char popChar = (char) pop;                res.append(popChar).append(" ");            }else {                res.append(pop).append(" ");            }        }        //将结果字符串反转返回后缀表达式        String s = res.toString();        String[] s1 = s.split(" ");        StringBuilder builder = new StringBuilder();        for (int i = s1.length-1; i >= 0; i--) {            builder.append(s1[i]).append(" ");        }        return builder.toString();    }

“Java怎么用栈实现综合计算器”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Java怎么用栈实现综合计算器

本文链接: https://www.lsjlt.com/news/341100.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java怎么用栈实现综合计算器
    本篇内容介绍了“Java怎么用栈实现综合计算器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!栈栈(stack)又名堆栈,它是一种运算受限的线...
    99+
    2023-07-02
  • Java用栈实现综合计算器
    目录栈Java实现栈栈实现综合计算器1.中缀表达式直接计算2.后缀表达式计算中缀表达式转后缀表达式栈 栈(stack)又名堆栈,它是一种运算受限的线性表 。限定仅在表尾进行插入和删除...
    99+
    2024-04-02
  • Java数据结构之栈与综合计算器的实现
    目录1.栈1.1 栈的简介1.2 使用数组模拟栈1.3 栈的测试2.综合计算器的实现2.1 需求简介2.2 详细思路及分步图解2.3 完整代码及测试1.栈 1.1 栈的简介 栈(st...
    99+
    2022-11-13
    Java 栈 综合计算器 Java 栈 Java 综合计算器
  • 栈的应用-综合计数器的实现
    目录 前言 一、思路分析 二、代码实现 总结 前言 在实现综合计数器之前,大家应该先了解一下什么是前中后缀表达式 前缀、中缀和后缀表达式是表示数学表达式的三种不同方式。 前缀表达式(也称为波兰式或前缀记法):操作符位于操作数之前。例...
    99+
    2023-09-25
    java 数据结构
  • Java怎么利用栈实现简易计算器功能
    这篇文章主要介绍了Java怎么利用栈实现简易计算器功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java怎么利用栈实现简易计算器功能文章都会有所收获,下面我们一起来看看吧。一、思路分析当我们输入一个类似于“...
    99+
    2023-06-30
  • Java利用栈实现简易计算器功能
    利用栈实现一个简易计算器(Java实现),供大家参考,具体内容如下 一、思路分析 当我们输入一个类似于“7*2+100-5+3-4/2”的简单中缀表达式时,我...
    99+
    2024-04-02
  • Python中怎么使用栈实现简易计算器
    这篇文章主要介绍“Python中怎么使用栈实现简易计算器”,在日常操作中,相信很多人在Python中怎么使用栈实现简易计算器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中怎么使用栈实现简易计算器...
    99+
    2023-06-02
  • 怎么用Java实现计算器
    这篇文章主要介绍“怎么用Java实现计算器”,在日常操作中,相信很多人在怎么用Java实现计算器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用Java实现计算器”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-20
  • Java实现计算器设计
    本文实例为大家分享了Java实现计算器设计的具体代码,供大家参考,具体内容如下 需求分析 目的是实现一个基于Java的可以求解带括号加减乘除表达式的带界面的计算器。 ...
    99+
    2024-04-02
  • 怎么用Java实现简单计算器功能
    这篇文章主要讲解了“怎么用Java实现简单计算器功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Java实现简单计算器功能”吧!一 项目说明实训目的:掌握 Java GUI 开发中的...
    99+
    2023-06-20
  • java实现计算器的代码怎么写
    以下是一个简单的Java代码实现计算器的示例:```javaimport java.util.Scanner;public class Calculator {public static void main(String[] args)...
    99+
    2023-08-11
    java
  • Java怎么实现图形界面计算器
    这篇文章主要介绍“Java怎么实现图形界面计算器”,在日常操作中,相信很多人在Java怎么实现图形界面计算器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么实现图形界面计算器”的疑惑有所帮助!接下来...
    99+
    2023-06-25
  • Java结合Kotlin实现宝宝年龄计算
    目录通过生日计算宝宝多大了输出结果再来一个Kotlin版输出结果通过生日计算宝宝多大了 前段时间大家在打新冠状疫苗的时候,护士给了我一张小纸条,上面清晰的显示我在地球上的年龄26岁4...
    99+
    2024-04-02
  • java swing怎么实现简单计算器界面
    这篇文章主要介绍“java swing怎么实现简单计算器界面”,在日常操作中,相信很多人在java swing怎么实现简单计算器界面问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java&...
    99+
    2023-06-30
  • JS怎么实现计算器
    这篇文章主要为大家展示了“JS怎么实现计算器”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JS怎么实现计算器”这篇文章吧。<!DOCTYPE h...
    99+
    2024-04-02
  • 用Java实现简单计算器功能
    本项目为大家分享了Java实现简单计算器功能的具体代码,供大家参考,具体内容如下 一 项目说明 实训目的:掌握 Java GUI 开发中的布局管理和事件处理机制。 实训要求: (1...
    99+
    2024-04-02
  • Java中怎么实现分布式计算
    Java中怎么实现分布式计算,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。远程过程调用的设计要创建出4种东西:服务器、客户端、服务器辅助设施和客户端辅助设施.创...
    99+
    2023-06-17
  • 怎么用javascript实现计算器功能
    这篇文章将为大家详细讲解有关怎么用javascript实现计算器功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 用javascript实现...
    99+
    2024-04-02
  • java GUI实现加法计算器
    本文实例为大家分享了java GUI实现加法计算器的具体代码,供大家参考,具体内容如下 1.写出一个简易计算器需要的组件 2.先出监听事件类 public class TextC...
    99+
    2024-04-02
  • Java栈与队列怎么实现
    本篇内容主要讲解“Java栈与队列怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java栈与队列怎么实现”吧!1、实现循环队列【OJ链接】循环队列一般通过数组实现。我们需要解决几个问题。...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作