利用栈使用简易计算器(Java实现)

作者:dreamer_it 时间:2023-07-22 02:02:11 

题目:使用栈计算类似表达式:5+2*3-2  的计算结果 

提示:简易计算器操作符号限于+,-,*,/的计算

分析思路:

1、创建一个数栈和一个符号栈,数栈用于存放数字,符号栈用于存放符号

2、创建一个索引index,用于遍历表达式

3、扫描表达式,如果是数字直接进入数栈,如果是符号,则需要进行判断。分两种情况,一是当符号栈如果为空,直接将符号入栈。二是不为空,先比较当前栈顶的符号与将要进栈的符号的优先级大小,如果将要进栈的操作符的优先级小,则将数栈的两个数弹出,符号栈的操作符弹出一个,并进行计算,计算之后的结果直接进入数栈,如果优先级大,就直接进栈。

4、扫描完表达式之后,就顺序的从数栈和符号栈顺序的弹出相应的数字和操作符,并进行计算。

5、当符号栈为空时,说明已经计算完了,此时留在数栈的只有一个数字,就是表达式计算之后的结果。

利用栈使用简易计算器(Java实现) 

代码实现


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
  • asp之家 软件编程 m.aspxhome.com