利用栈使用简易计算器(Java实现)
作者:dreamer_it 时间:2023-07-22 02:02:11
题目:使用栈计算类似表达式: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
标签:java,栈,计算器
0
投稿
猜你喜欢
JVM完全解读之GC日志记录分析
2022-09-22 12:43:08
解决Eclipse/STS中出现Resource is out of sync with the file system的异常问题
2022-02-12 22:35:20
C#基于WinForm实现串口通讯
2023-12-26 02:03:39
C# memcached缓存使用实例代码
2022-01-15 02:17:11
Java深入探究Object类的方法
2022-11-24 06:48:53
Java 自定义动态数组方式
2022-08-26 01:38:37
深入了解Java设计模式之策略模式
2021-06-24 22:45:56
C# 设计模式系列教程-策略模式
2022-04-30 16:09:03
java异常(Exception)处理机制详解
2023-06-06 08:21:48
Android使用多线程进行网络聊天室通信
2022-05-11 18:56:36
Android 加载大图及多图避免程序出现OOM(OutOfMemory)异常
2022-05-06 18:32:06
jdk-logging log4j logback日志系统实现机制原理介绍
2022-03-22 11:45:28
java之assert关键字用法案例详解
2022-07-10 23:01:32
Android实现数字跳动效果的TextView方法示例
2023-05-24 16:54:29
C# 中的IComparable和IComparer的使用及区别
2023-04-19 20:11:55
Java线程通信之wait-notify通信方式详解
2022-05-17 19:35:46
Android开发gradle拉取依赖的加速配置
2023-05-31 03:16:08
Kafka常用命令之kafka-console-consumer.sh解读
2022-06-11 00:20:32
Java设计模式之桥接模式的示例详解
2023-10-03 21:56:00
SpringBoot SpEL语法扫盲与查询手册的实现
2022-06-02 23:52:39