棧實現計算器(簡單四則運算)


主要是通過定義一個數棧和一個符號棧,並根據給出的計算式進行拆分,循環判斷是數字還是符號,考慮數字的連續性和符號計算的優先級,具體實現如下:

package com.pangzi.stucture;

public class calculator {

public static void main(String[] args) {
String expression = "50+9*9-7";//定義一個需要被掃描的表達式
//創建兩個棧,一個數棧,一個符號棧
ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operStack = new ArrayStack2(10);
//定義需要的變量
int index = 0;//定義一個指向數字和運算符的索引,掃描棧中的內容
int num1 = 0;//定義第一個數字
int num2 = 0;//定義第二個數字
int oper = 0;//定義操作符
int res = 0;//定義運算結果
char ch = ' ';//將每次掃描得到的char保存至ch里面
String keepNum = "";//用於拼接多位數
//開始掃描表達式
while(true){
//依次得到expression中的每一個字符
ch = expression.substring(index, index+1).charAt(0);//用substr獲取長度為1的一個個字符串,然后通過charat轉換為字符。
//判斷字符是數字還是運算符,然后進行處理
if(operStack.isOper(ch)){//如果ch是一個符號
//判斷符號棧是否為空
if(!operStack.isEmpty()){
//如果符號棧不為空,用ch和符號棧存在的運算符進行比較,如果ch的優先級小於等於棧中符號的優先級
//就從數棧中彈出兩個數字,進行運算並將得到的結果放入數棧,然后將ch入符號棧
if(operStack.priority(ch) <= operStack.priority(operStack.peek())){
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res);
operStack.push(ch);
}else{
//如果當前操作符的優先級大於符號棧中的優先級,直接入符號棧
operStack.push(ch);
}
}else{
//如果符號棧為空,進行入棧操作
operStack.push(ch);//將ch入符號棧
}
}else{//如果ch是數據的話,則直接入數棧
//numStack.push(ch - 48);//根據ascii表換算
//當處理多位數時,不能掃描到數字時就立即入棧,因為有可能是多位數
//在處理時,應該在expression的表達式后面在掃描一位,如果是數繼續掃描,如果是符合則停止。
//定義一個字符串變量用於拼接數字,keepNum

keepNum += ch;

//判斷ch是不是expression表達式的最后一位,如果是最后一位則直接入棧即可
if(index == expression.length() - 1){
numStack.push(Integer.parseInt(keepNum));//將keepNum轉換為int,並入棧
}else{

//判斷keepNum的后面一位是不是數字,如果是數字就繼續掃描,如果不是則不掃描進行入棧
if(operStack.isOper(expression.substring(index+1, index+2).charAt(0))){
//如果后一位是運算符,則入棧
numStack.push(Integer.parseInt(keepNum));//將keepNum轉換為int,並入棧
//清空keepNum
keepNum = "";
}
}

}
//讓index+1,看是否掃描到最后一個字符
index++;
if(index >= expression.length()){
break;//如果掃描到了最后就跳出循環
}
}
//當expression掃描完畢后,就依次從數棧和符號棧中彈出進行運算。
while(true){
//如果符號棧為空,則任務已經計算到最后的結果了,數棧中只有一個數字,就是結果
if(operStack.isEmpty()){
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res);//入棧
}
System.out.printf("表達式%s = %d",expression,numStack.pop());//將最后的結果打印出來
}
}

//定義一個表示棧的類
class ArrayStack2{
private int maxSize;//定義棧的容量
private int[] stack;//定義存儲棧數據的數組
private int top = -1;//定義棧頂,初始為-1

//定義構造函數
public ArrayStack2(int maxSize){
this.maxSize = maxSize;
stack = new int[this.maxSize];//初始化數組
}

//獲得棧頂的值
public int peek(){
return stack[top];
}

//判斷棧是否滿了
public boolean isFull(){
return top == maxSize - 1;//如果棧頂等於容量減一的時候,棧就滿了
}

//判斷棧是否空
public boolean isEmpty(){
return top == -1;
}

//入棧 push
public void push(int value){
//先判斷棧是否滿了,滿了無法入棧
if(isFull()){
System.out.println("棧已滿,無法入棧");
return;
}
top++;
stack[top] = value;//將新入棧的數據放入數組
}

//出棧 pop
public int pop(){
//先判斷是否為空棧
if(isEmpty()){
//拋出異常
throw new RuntimeException("棧已空");
}
int value = stack[top];//獲取彈棧的值
top--;
return value;//返回彈棧的值
}

//顯示棧的情況,遍歷時需要從棧頂往下走
public void list(){
if(isEmpty()){ //判空
System.out.println("棧空,無數據");
return;
}
for(int i = top;i>=0;i--){
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}

//返回運算符的優先級,優先級人為來確定的,優先級用數字表示,數字越大優先級越高
public int priority(int oper){
if(oper == '*' || oper == '/'){
return 1;//乘除的優先級為1
}else if(oper == '+' || oper == '-'){
return 0;//加減的優先級為1
}else{
return -1;//有問題返回-1
}

}

//判斷是否是一個運算符
public boolean isOper(char val){
return val =='+' || val == '-' || val == '*' || val == '/';
}

//計算方法
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;//注意順序,由棧中后彈出的值除先彈出的
break;
}
return res;
}
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM