java模擬棧的操作

    棧是一種有序列表,可以使用數組的結構來儲存棧的數據內容

思路
 1. 創建一個棧類StackArray
2. 定義一個top來模擬棧頂,初始化為-1
3. 入棧: 當有數據加入到棧的時候 top++ stack[top] = data
4. 出棧 int value = stack[top]; top--, return value

代碼實現
//定義一個類來表示棧  class ArrayStack{      private int maxSize; //棧的大小      private int[] stack; //數組模擬棧 數據放在數組中      private int top = -1; //top 表示棧頂        //構造器      public ArrayStack(int maxSize) {          this.maxSize = maxSize;          stack = new int[maxSize];      }        //棧滿 當棧頂和棧容量相等時 棧滿      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]=%dn", i,stack[i]);          }      }      }

 

通過main方法調用自定義的棧類來模擬棧的操作

public class StackArrayDemo {      public static void main(String[] args) {          //測試ArrayStack          //創建一個ArrayStack對象          ArrayStack stack = new ArrayStack(4);          String key = "";          boolean loop = true; //控制是否退出菜單          Scanner scanner = new Scanner(System.in);            while (loop){              System.out.println("show:  表示顯示棧");              System.out.println("exit:  退出程序");              System.out.println("push:  表示添加數據到棧");              System.out.println("pop:   表示從棧取出數據");              System.out.println("請輸入你的選擇: ");              key = scanner.next();              switch (key){                  case "show":                      stack.list();                      break;                  case "push":                      System.out.println("請輸入一個數: ");                      int value = scanner.nextInt();                      stack.push(value);                      break;                  case "pop":                      try{                          int result = stack.pop();                          System.out.printf("取出的數據為:%dn", result);                      }catch (Exception e){                          System.out.println(e.getMessage());                      }                      break;                  case "exit":                      scanner.close();                      loop = false;                      break;                  default:                      break;                }            }          System.out.println("程序退出");      }  }

 

根據上邊的內容 來模擬一下用棧實現的計算表達式的功能

思路

 

通過一個index(索引) 來遍歷我們的表達式
如果我們發現是一個數字 就直接入數棧
如果掃描到的是一個符號 就分如下情況
1.如果當前符號棧為空, 就直接入棧
2.如果符號棧有操作符 就進行比較 如果當前操作符的優先級 小於或等於棧中的操作符
就需要從數棧中pop出兩個數,再從符號棧中pop出一個符號,進行運算,將得到的結果入數棧
再把當前的符號入符號棧,
3.如果當前符號的優先級大於棧中的操作符,直接入棧
掃描完畢後 就順序地沖數棧和符號棧中pop出響應的數和符號 並運行
最後在數棧中只有一個數字就是表達式的結果

參考上邊的ArrayStack類 拓展一個ArrayStack2 類 並對功能進行增強
//定義一個類來表示棧 對ArrayStack進行擴展  class ArrayStack2{      private int maxSize; //棧的大小      private int[] stack; //數組模擬棧 數據放在數組中      private int top = -1; //top 表示棧頂        //構造器      public ArrayStack2(int maxSize) {          this.maxSize = maxSize;          stack = new int[maxSize];      }        //棧滿 當棧頂和棧容量相等時 棧滿      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]=%dn", i,stack[i]);          }      }        //返回運算符的優先級,優先級由程序員來確定      //優先級數字越大 則優先級越高      public int priority(int oper){          if(oper == '*' || oper == '/'){              return 1;          }else if(oper == '+' || oper == '-'){              return 0;          }else {              return -1;  //假定目前的計算式只有 + - * / 四種          }      }      //判斷是不是一個運算符      public boolean isOper(char val){          return val == '+' || val == '-' || val == '*' || val == '/';      }        // 計算方法      public int cal(int oper, int num1, int num2){          int result = 0; // 用於存放計算的結果          switch (oper){              case '+':                  result = num1 + num2;                  break;              case '-':                  result = num2 - num1;                  break;              case '*':                  result = num2 * num1;                  break;              case '/':                  result = num2 / num1;                  break;              default:                  break;          }            return result;      }        //返回棧頂的值 不Pop      public int peek(){          return stack[top];      }      }

 

調用主方法 進行案例的具體實現

public class StackCalculate {      public static void main(String[] args) {          //完成表達式的運算          String expression = "500+7*2-8";          //創建兩個棧 一個數棧一個符號棧          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);              //判斷ch是什麼 然後做相應的處理              if (operStack.isOper(ch)){ //如果是運算符                  //判斷當前的符號棧是否為空                  if(!operStack.isEmpty()){                      /*                       處理,進行符號優先級比較如果當前操作符的優先級 小於或等於棧中的操作符                      就需要從數棧中pop出兩個數,再從符號棧中pop出一個符號,進行運算,將得到的結果入數棧                      再把當前的符號入符號棧,                      如果當前符號的優先級大於棧中的操作符,直接入棧                       */                      if (operStack.priority(ch) <= operStack.priority(operStack.peek())){                          //獲取數棧的數據和符號棧的運算符                          num1 = numStack.pop();                          num2 = numStack.pop();                          oper = operStack.pop();                          //運算                          res = numStack.cal(oper,num1, num2);                          //將運算結果壓入數棧                          numStack.push(res);                          //將當前運算符壓入符號棧                          operStack.push(ch);                      }else {                          operStack.push(ch);                      }                    }else {                      //為空 直接入棧、                      operStack.push(ch);                  }                }else {                  //如果ch是數字 直接入數棧                 // numStack.push(ch - 48); // ASCII碼轉換成int                  //當處理多位數時 有可能是多位數 因此 需要定義一個字符串變量 用於拼接                  keepNum += ch;                  //如果ch已經到expression的最後一位了直接入棧                  if (index == expression.length() - 1){                      numStack.push(Integer.parseInt(keepNum));                  } else if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))){                      // 如果後一位是運算符則入棧                      numStack.push(Integer.parseInt(keepNum));                      //!!重要的  清空keepNum                      keepNum = "";                  }                }              //index ++ 判斷是否掃描到表達式最後的位置              index++;              if (index >= expression.length()){                  break;              }          }            //表達式掃描完畢後 從棧中pop出符號和數據 進行運算          while (true){              //如果符號棧為空 則計算結束 獲取最後的結果 此時數棧只有一個數字              if (operStack.isEmpty()){                  break;              }              num1 = numStack.pop();              num2 = numStack.pop();              oper = operStack.pop();              //運算              res = numStack.cal(oper,num1, num2);              numStack.push(res);          }          //將最後的計算結果pop出          int finalRes = numStack.pop();          System.out.printf("表達式%s = %d", expression, finalRes);      }  }