数据结构:栈实现简易计算器
生活随笔
收集整理的這篇文章主要介紹了
数据结构:栈实现简易计算器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 棧實現簡易計算器
- 思路
- 代碼實現
- 棧結構
- 運算方法
- 測試
棧實現簡易計算器
之前的博客已經介紹了棧數據結構,棧有著數據先進后出的特點,因此用于實現簡易計算器時相當方便。本博文中將介紹如何用棧實現一個可以進行簡單四則運算不含括號的簡易計算器(中綴表達式)
思路
- 首先創建兩個棧,一個用于存儲數而另一個用于存儲運算符號。
- 首先需要一個index索引來遍歷表達式
- 遍歷到數字時直接入數棧
- 遍歷到運算符時需要分情況討論
- 如果當前符號棧為空直接入棧
- 如果當前符號棧不為空需要分情況討論
- 當前遍歷到的運算符的運算優先級小于或者等于棧中的運算符優先級,先從數棧中取出兩個數和從字符棧中取出一個運算符,將其進行運算之后將得到的新的數存入數棧,最后將當前遍歷到的運算符存入字符棧
- 當前遍歷到的運算符的運算優先級大于棧中的運算符優先級則直接存入字符棧
- 當表達式遍歷完之后,從數棧和符號棧依次取出相應的數和符號并計算
- 當數棧只剩下一個數字時,計算完畢,此時該數為最終結果。
代碼實現
棧結構
用之前的方法用數組模擬棧
class CalculatorStack {private int maxSize;private int[] stack;private int top = -1;public CalculatorStack(int maxSize) {this.maxSize = maxSize;stack = new int[maxSize];}/**** @return 返回棧頂的數據<不彈出數據>*/public int peek(){return stack[top];}public boolean isFull(){return top == maxSize - 1;}public boolean isEmpty(){return top == -1;}public void push(int value){if (isFull()){throw new RuntimeException("棧滿無法添加數據....");}top++;stack[top] = value;}public int pop(){if (isEmpty()){throw new RuntimeException("棧空無法返回數據....");}return stack[top--];}}運算方法
/*** 返回運算符的優先級* @param operation* @return 返回數字代表優先級 數字越大優先級越高*/ public int getPriority(int operation) {if (operation == '*' || operation == '/'){return 1;}else if (operation == '+' || operation == '-'){return 0;}else{throw new RuntimeException("輸入操作符有誤!");} }/*** 判斷是否是運算符* @param val* @return*/ public boolean isOperation(int val) {return val == '+' || val == '-' || val == '*' || val == '/'; }private int calculate(int num1,int num2,int operation) {int result = 0;switch (operation){case '+':result = num2 + num1;break;case '-'://注意順序result = num2 - num1;break;case '*':result = num2 * num1;break;case '/'://注意順序result = num2 / num1;break;}return result; }核心方法
public static void calculate(String expression) {//創建兩個棧 一個數棧 一個符號棧CalculatorStack numStack = new CalculatorStack(2002);CalculatorStack operationStack = new CalculatorStack(519);//定義相關變量int index = 0;int num1,num2,result;int operation;//用于拼接多位數String keepNum = "";while (true){//依次得到expression中的每一個字符char ch = expression.substring(index, index + 1).charAt(0);//如果是運算符if (operationStack.isOperation(ch)){//判斷符號棧是否為空if (!operationStack.isEmpty()){//如果當前操作符優先級大于棧中的所有操作符,直接入棧if (operationStack.getPriority(ch) > operationStack.getPriority(operationStack.peek())){operationStack.push(ch);}//如果當前操作符的優先級小于或等于棧中的操作符,先彈出符號棧棧頂的操作符和數棧的頭兩個數據else{num1 = numStack.pop();num2 = numStack.pop();operation = operationStack.pop();result = numStack.calculate(num1,num2,operation);//運算結果入數棧numStack.push(result);//符號ch入符號棧operationStack.push(ch);}}else{//符號棧為空直接入棧operationStack.push(ch);}}//如果是數直接入數棧else{//1.當處理多位數時,不可以直接入棧,可能是多位數//2.處理多位數時需要看expression表達式index位置的后一位是什么,如果是數字需要繼續讀取否則直接入棧//3.因此需要定義一個變量字符串用于拼接數字keepNum+=ch;//如果當前處于表達式的末尾if (index == expression.length() - 1){numStack.push(Integer.parseInt(keepNum));keepNum = "";}else{//判斷下一位是否是字符if (operationStack.isOperation(expression.substring(index+1,index+2).charAt(0))){numStack.push(Integer.parseInt(keepNum));//重置keepNum!!!!!keepNum = "";}//1 != '1' ---> 1 = '1' - 48;//numStack.push(ch - 48);}}//讓index+1,并且判斷是否掃描到expression最后index++;if (index >= expression.length()){break;}}//當表達式掃描完畢就順序地從數棧和符號棧中取出相應的數和符號while (true){//如果符號棧為空--->計算完畢if (operationStack.isEmpty()){break;}num1 = numStack.pop();num2 = numStack.pop();operation = operationStack.pop();result = numStack.calculate(num1,num2,operation);numStack.push(result);}result = numStack.pop();System.out.printf("表達式:%s=%d",expression,result); }測試
public class Calculator {public static void main(String[] args){String expression = "100+20*2-4";CalculatorStack.calculate(expression);} }//-----------------------------------------------------測試結果---------------------------------------------------- 表達式:100+20*2-4=136以上。
如有不足或錯誤歡迎評論指正
總結
以上是生活随笔為你收集整理的数据结构:栈实现简易计算器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构:循环链表解决约瑟夫问题
- 下一篇: 数据结构:栈实现逆波兰计算器