棧還是用的上一篇的數組模擬棧,並在此之上增加了
判斷是否是一個運算符的方法
獲取運算符的優先級方法
計算結果方法
查看棧頂元素的方法
四個方法,具體代碼如下:
package com.ebiz.stack; /** * @author YHj * @create 2019-07-20 14:20 * 數組模擬棧 */ public class ArrayStack { private int maxSize; private int [] arr; //數組模擬棧 private int top = -1; //構造方法,初始化數組 public ArrayStack(int maxSize) { this.maxSize=maxSize; this.arr = new int[maxSize]; } //驗證棧滿 public boolean isFull(){ return top == maxSize-1; } //驗證為空 public boolean isEmpty(){ return top == -1; } //入棧 public void push(int value){ if (isFull()){ System.out.println("棧已滿"); return; } top++; arr[top]=value; } //出棧 public int pop(){ if(isEmpty()){ throw new RuntimeException("棧已空"); } int value=arr[top]; top--; return value; } //遍歷棧 public void list(){ if (isEmpty()){ throw new RuntimeException("棧為空"); } while (true){ if (isEmpty()){ System.out.println("棧為空"); break; } System.out.printf("出站元素為%d%n",arr[top]); top--; } } //返回運算符的優先級 優先級用數字表示 //數字越大,代表優先級越高 // *或者/ 優先級為1 // +或者- 優先級為0 // -1 代表運算符為問題運算符 public int priority(int operator){ if ('*' == operator || '/' == operator){ return 1; }else if ('+' == operator || '-' == operator){ return 0; }else{ return -1; } } //判斷是否為一個運算符 public boolean isOperator(char operator){ return operator == '+' || operator == '-' || operator == '*' || operator == '/'; } //計算方法 public int calculator(int num01,int num02,int operator){ //用於存放計算結果 int result=0; switch (operator){ case '+': result = num01+num02; break; case '-': result = num02-num01; break; case '*': result = num01*num02; break; case '/': result = num02/num01; break; default: break; } return result; } //獲取符號棧的棧頂符號,並不是真正取出該元素 public int peek() { return arr[top]; } }
下面給出測試,中綴表達式提前給定好,只涉及到了兩位數,對於小括號還有小數點后面會將中綴轉為后綴,便於計算
package com.ebiz.stack; /** * @author YHj * @create 2019-07-22 11:04 * 棧模擬計算器 中綴表達式 */ public class Calculator { public static void main(String[] args) { //表達式 //String expression = "50+2*6-2"; String expression = "5-2*3+1"; //創建數字棧 ArrayStack numeStack = new ArrayStack(10); //創建運算符棧 ArrayStack operatorStack = new ArrayStack(10); //初始化索引,用於掃描表達式 int index = 0; int num01 = 0; int num02 = 0; int operator = ' '; //定義運算符 int res =0; //存放結果 char ch =' '; //將每次掃描得到的char保存到ch // 定義字符串,拼接多位數 String str=""; while (true){ //開始掃描表達式,並判斷是數字還是符號 ch=expression.substring(index,index+1).charAt(0); //如果為運算符 if (operatorStack.isOperator(ch)){ //判斷符號棧是否為空 符號棧不為空 if (!operatorStack.isEmpty()){ //判斷符號優先級 當前符號優先級小於或者等於符號棧頂的符號的優先級, //從數字棧彈出兩個數字,符號棧彈出棧頂符號,進行計算,結果加入數字棧,當前符號加入符號棧 if (operatorStack.priority(ch) <= operatorStack.priority(operatorStack.peek())){ num01=numeStack.pop(); num02=numeStack.pop(); operator=operatorStack.pop(); //進行計算 res=numeStack.calculator(num01,num02,operator); operatorStack.push(ch); numeStack.push(res); }else { //當前符號的優先級大於符號棧頂的符號的優先級,則直接加入符號棧 operatorStack.push(ch); } }else { //符號棧為空 operatorStack.push(ch); } }else { //不是運算符 直接進入樹棧 //ASCII表, 查出來的是'1' 對應的十進制為49 //numeStack.push(ch-48); //某一字符為多位數時,需要當成字符串處理 str+=ch; //判斷ch是否為最后一個字符 if (index == expression.length()-1){ numeStack.push(Integer.parseInt(str)); }else { //判斷下一位是否是字符,下一位是字符,則將當前拼接字符串存入數字棧 if (operatorStack.isOperator(expression.substring(index+1,index+2).charAt(0))){ numeStack.push(Integer.parseInt(str)); //把str 清空 str = ""; } } } //繼續掃描,索引增加,並判斷是否到最后 index++; if (index >= expression.length()){ break; } } //表達式掃描完畢后,對兩個棧中元素進行計算 while (true){ num01=numeStack.pop(); num02=numeStack.pop(); operator=operatorStack.pop(); numeStack.push(numeStack.calculator(num01, num02, operator)); //判斷結束 if (operatorStack.isEmpty()){ break; } } //輸出結果 System.out.println("result="+numeStack.pop()); } }