我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

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

下载Word文档

猜你喜欢

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

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

Java数据结构之栈与综合计算器的实现

这篇文章主要为大家详细介绍了Java数据结构中栈与综合计算器的实现,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以了解一下
2022-11-13

Java怎么利用栈实现简易计算器功能

这篇文章主要介绍了Java怎么利用栈实现简易计算器功能的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java怎么利用栈实现简易计算器功能文章都会有所收获,下面我们一起来看看吧。一、思路分析当我们输入一个类似于“
2023-06-30

Python中怎么使用栈实现简易计算器

这篇文章主要介绍“Python中怎么使用栈实现简易计算器”,在日常操作中,相信很多人在Python中怎么使用栈实现简易计算器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中怎么使用栈实现简易计算器
2023-06-02

怎么用Java实现计算器

这篇文章主要介绍“怎么用Java实现计算器”,在日常操作中,相信很多人在怎么用Java实现计算器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用Java实现计算器”的疑惑有所帮助!接下来,请跟着小编一起来
2023-06-20

怎么用Java实现简单计算器功能

这篇文章主要讲解了“怎么用Java实现简单计算器功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Java实现简单计算器功能”吧!一 项目说明实训目的:掌握 Java GUI 开发中的
2023-06-20

java实现计算器的代码怎么写

以下是一个简单的Java代码实现计算器的示例:```javaimport java.util.Scanner;public class Calculator {public static void main(String[] args) {
2023-08-11

Java怎么实现图形界面计算器

这篇文章主要介绍“Java怎么实现图形界面计算器”,在日常操作中,相信很多人在Java怎么实现图形界面计算器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么实现图形界面计算器”的疑惑有所帮助!接下来
2023-06-25

java swing怎么实现简单计算器界面

这篇文章主要介绍“java swing怎么实现简单计算器界面”,在日常操作中,相信很多人在java swing怎么实现简单计算器界面问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java swing怎么实现简
2023-06-30

Java中怎么实现一个通用组合算法

Java中怎么实现一个通用组合算法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java实现通用组合算法,存在一个类似{31311133,33113330}这样的集合,经过
2023-06-17

Java中怎么实现分布式计算

Java中怎么实现分布式计算,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。远程过程调用的设计要创建出4种东西:服务器、客户端、服务器辅助设施和客户端辅助设施.1
2023-06-17

Java中怎么实现一个计算器小程序

Java中怎么实现一个计算器小程序,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。代码如下:package tst.jframe; import java.awt
2023-06-20

java怎么实现计数器

在Java中,可以使用变量来实现计数器。首先,声明一个整型变量来存储计数器的值,然后利用循环结构不断对计数器进行更新。以下是一个简单的示例代码:```javapublic class Counter {private int count;p
2023-08-31

java中怎么利用gui实现一个计算器小程序

java中怎么利用gui实现一个计算器小程序,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。代码:package gui; i
2023-06-20

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录