利用栈使用简易计算器(Java实现)
作者:dreamer_it 发布时间:2023-07-22 02:02:11
标签:java,栈,计算器
题目:使用栈计算类似表达式:5+2*3-2 的计算结果
提示:简易计算器操作符号限于+,-,*,/的计算
分析思路:
1、创建一个数栈和一个符号栈,数栈用于存放数字,符号栈用于存放符号
2、创建一个索引index,用于遍历表达式
3、扫描表达式,如果是数字直接进入数栈,如果是符号,则需要进行判断。分两种情况,一是当符号栈如果为空,直接将符号入栈。二是不为空,先比较当前栈顶的符号与将要进栈的符号的优先级大小,如果将要进栈的操作符的优先级小,则将数栈的两个数弹出,符号栈的操作符弹出一个,并进行计算,计算之后的结果直接进入数栈,如果优先级大,就直接进栈。
4、扫描完表达式之后,就顺序的从数栈和符号栈顺序的弹出相应的数字和操作符,并进行计算。
5、当符号栈为空时,说明已经计算完了,此时留在数栈的只有一个数字,就是表达式计算之后的结果。
代码实现
package cn.mrlij.stack;
import java.util.Arrays;
import java.util.Scanner;
/**
* 使用数组实现栈
*
* @author dreamer
*
*/
public class ArrayStackDemo {
public static void main(String[] args) {
String express = "5011+2*3-2";
int index = 0;//定义一个索引值,用于遍历表达式
int num1 = 0;
int num2 = 0;
int res = 0;//计算结果
char ch = ' ';
int oper = 0;
String keepNum = "";
ArrayStack numStack = new ArrayStack(10);//创建一个数栈
ArrayStack operStack = new ArrayStack(10);//创建一个符号栈
while (true){
ch = express.substring(index,index+1).charAt(0);//不停的遍历操作符
//判断是否是操作符
if (operStack.isOper(ch)){
//判断当前符号栈是否有符号存在
if(!operStack.isEmpty()){
//不为空则判断优先级
if(operStack.priority(ch)<=operStack.priority(operStack.peek())){
//当优先级小于栈顶的值时候,弹出两个数栈的值进行计算
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = operStack.cal(num1,num2,oper);
//计算以后将计算得到的值放入数栈
numStack.push(res);
//同时将此时的操作符放入符号栈
operStack.push(ch);
}else{
//优先级
operStack.push(ch);
}
}else{
//为空直接将符号入栈
operStack.push(ch);
}
}else {
keepNum += ch;
//处理多位数
if(express.length()-1 == index){
numStack.push(Integer.parseInt(keepNum));
}else {
if(operStack.isOper(express.substring(index+1,index+2).charAt(0))){
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
// numStack.push(ch-48);
}
index++;
if(index >= express.length()){
break;
}
}
//扫描完之后,将数栈的值,与操作符中的值进行计算
while (true){
if(operStack.isEmpty()){
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = operStack.cal(num1,num2,oper);
numStack.push(res);
}
System.out.println("表达式:"+express+"="+numStack.pop());
}
}
class ArrayStack {
private int MaxSize;// 定义数组的最大长度
private int[] arr;// 定义数组,数据就放在该数组
private int top = -1;// 定义栈顶,初始化数据为-1
public ArrayStack(int maxSize) {
this.MaxSize = maxSize;
arr = new int[MaxSize];
}
// 判断数组是否为空
public boolean isEmpty() {
return top == -1;
}
// 判断数组是否满了
public boolean isFull() {
//System.out.println("栈顶:" + top + "最大长度:" + MaxSize);
return top == MaxSize - 1;
}
//取出棧頂元素
public int peek(){
return arr[top];
}
// 进栈
public void push(int val) {
// 先判断栈是否满了,满了就不能添加进去
if (isFull()) {
System.out.println("栈已经满了~~");
return;
}
top++;
arr[top] = val;
}
// 出栈
public int pop() {
// 先判断栈是否为空
if (isEmpty()) {
throw new RuntimeException("栈为空,无法出栈!");
}
int val = arr[top];
top--;
return val;
}
public void show() {
if (isEmpty()) {
System.out.println("没有数据");
return;
}
for (int i = top; i >= 0; i--) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
/**
* 判断是否是一个操作符
* @param oper 传入的字符
* @return 如是操作符返回true,否则返回false
*/
public boolean isOper(char oper){
return oper == '+' || oper == '-' || oper =='*' || oper == '/';
}
/**
* 判断操作符的优先级
* @param oper 传入的优先级
* @return 返回优先级 分别是1,-1,0
*/
public int priority(int oper ){
if(oper == '*' || oper == '/'){
return 1;
} else if(oper == '+' || oper == '-'){
return 0;
}else {
return -1;
}
}
//计算方法
public int cal(int num1,int num2,int oper){
int res = 0;
switch (oper){
case '+': res = num1 + num2;
break;
case '-': res = num2 - num1;
break;
case '*': res = num1 * num2;
break;
case '/': res = num2 /num1;
}
return res;
}
}
来源:https://blog.csdn.net/u013571044/article/details/101201059


猜你喜欢
- 项目需求:根据年级下拉框的变化使得科目下拉框绑定次年级下对应有的值我们用三层架构的模式来实现1.我们想和数据库交互,我们首先得来先解决DAL
- 概述1、ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任
- Android 调用系统应用的方法总结1、调用系统拍照Intent intent = new Intent("andr
- 数据库事务是后端开发中不可缺少的一块知识点。Spring为了更好的支撑我们进行数据库操作,在框架中支持了两种事务管理的方式: 编程式事务声明
- 本文实例为大家分享了Android仿iphone自定义滚动选择器的具体代码,供大家参考,具体内容如下一、多的不说,效果图,先走起二、实例源码
- JSTL JSTL简介:JSTL的全称:JSP Standard Tag Library,JSP标准标签库JSTL的作用:&nbs
- 前言Android12 有很多令人惊喜的变化,比如基于 Material You 的全新 UI,基于 SplashScreen 的应用启动画
- 前言在使用easyExcel读取文件时,对于Excel的表头,在解析读取时分成不同的状态,需要加以区分.1 环境准备准备一个可以正常访问的S
- 写在前面 众所周知,kafka是现代流行的消息队列,它使用经典的消息订阅发布模式实现消息的流转,大部分代码结合kaf
- 背景1> 大家都知道SpringBoot是通过main函数启动的,这里面跟踪代码到处都没有找到while(true),为什么启动后可以
- ImageManager2这个类具有异步从网络下载图片,从sd读取本地图片,内存缓存,硬盘缓存,图片使用动画渐现等功能,已经将其应用在包含大
- 在上篇文章给大家介绍了Android Bluetooth蓝牙技术初体验相关内容,感兴趣的朋友可以点击了解详情。一:蓝牙设备之间的通信主要包括
- 前言最近写了篇有关Eclipse工程转Android Studio工程的文章,而导致公司项目需要转 AS 的直接原因,就是今天要写的主题–方
- 前言Kotlin并没有想象中的那么牛逼哄哄,也并不难,我更喜欢把他看做一枚语法糖,所谓的语法糖就是:能够让代码变得更加简单易读的辅助工具。而
- 本文实例讲述了Android实现的简单蓝牙程序。分享给大家供大家参考,具体如下:我将在这篇文章中介绍了的Android蓝牙程序。这个程序就是
- spring boot实现自动输出word文档功能本文用到Apache POI组件组件依赖在pom.xml文件中添加<dependen
- 前言Spring Cloud默认为Zuul编写并启用了一些过滤器,这些过滤器有什么作用呢?我们不妨按照@EnableZuulServer、@
- IDEA快速创建getter和setter方法找到generate我的是Mac,右击鼠标就可以打开,相信windows也不难。选择gette
- PDF中的加数字签名是对文档权威性的有效证明。我们在向PDF文档添加签名时,需要准备可信任的签名证书。同时,对已有的签名,可验证签名是否有效
- 前言我们经常会被问到这么一个问题:SpringBoot相对于spring有哪些优势呢?其中有一条答案就是SpringBoot自动注入。那么自