1. 程式人生 > 其它 >棧(應用綜合計算器)

棧(應用綜合計算器)

數棧numStack:存放數  符號棧operStack:存放運算子

思路:

  1、通過一個index值 (相當於索引),遍歷表示式

  2、如果發現index掃描到是一個數字,直接入數棧

  3、如果掃描到時一個符號,分如下情況:

    1)如果當前符號棧為空,就直接入棧

    2)如果符號棧有操作符,就進行比較,

    如果當前操作符優先順序小於等於棧中的操作符

    需要從數棧中pop出兩個數,再從符號棧中pop出一個符號,進行運算,將得到的結果再入數棧,然後將當前操作符入符號棧。

    如果當前操作符優先順序大於棧中的操作符,就直接入符號棧

  4、當表示式臊面完畢,順序從數棧和符號棧中pop出相應的數和符號並運算

  5、最後數棧只有一個數字,就是表示式的結果

  1 import com.sun.org.apache.xpath.internal.objects.XBoolean;
  2 
  3 public class Calculator {
  4     public static void main(String[] args) {
  5         //
  6         String expression = "3+2*6-1";
  7         //建立兩個棧,數棧,一個符號棧
  8         ArrayStack2 numStack = new ArrayStack2(10);
9 ArrayStack2 operStack = new ArrayStack2(10); 10 //定義需要的相關變數 11 int index = 0;//用於掃描 12 int num1=0; 13 int num2=0; 14 int oper = 0; 15 int res = 0; 16 char ch = ' ';//將每次掃描到的char存到ch 17 //開始while迴圈的掃描expression 18 while(true
){ 19 //依次得到expression的每一個字元 20 ch = expression.substring(index,index+1).charAt(0); 21 //判斷ch是什麼,然後做相應的處理 22 if (operStack.isOper(ch)){//如果是運算子 23 //判斷當前的符號棧是否為空 24 if (!operStack.isEmpty()){ 25 //處理 26 if (operStack.priority(ch) <= operStack.priority(operStack.pick())){ 27 num1 = numStack.pop(); 28 num2 = numStack.pop(); 29 oper = operStack.pop(); 30 res = numStack.cal(num1,num2,oper); 31 //把運算的結果入數棧 32 numStack.push(res); 33 //讓後將當前的操作符入符號棧 34 operStack.push(ch); 35 }else { 36 operStack.push(ch); 37 } 38 }else{ 39 //如果為空直接入棧 40 operStack.push(ch);//1+3 41 42 } 43 }else{ 44 //如果是數,直接入數棧 45 numStack.push(ch-48);//字元1 不等於1,ASCII碼錶 46 47 //1.當處理多位數,不能發現是一個數就入棧,可能多位數 48 //2,在處理數,需要像expression的表示式index後再看一位,如果是數,繼續掃描 49 //3.因此需要定義一個變數字串,用於拼接 50 } 51 //讓index+1,並判斷是否掃描到expression最後 52 index++; 53 if (index >= expression.length()){ 54 break; 55 } 56 } 57 58 // 59 while(true){ 60 //如果符號棧為空,則計算到最後結果,數棧只有一個數值【結果】 61 if (operStack.isEmpty()){ 62 break; 63 } 64 num1 = numStack.pop(); 65 num2 = numStack.pop(); 66 oper = operStack.pop(); 67 res = numStack.cal(num1,num2,oper); 68 //把運算的結果入數棧 69 numStack.push(res); 70 } 71 int res2 = numStack.pop(); 72 System.out.printf("表示式%s=%d",expression,res2); 73 74 75 } 76 77 78 } 79 80 //定義一個ArrayStack表示棧,需要擴充套件功能 81 class ArrayStack2 { 82 private int maxSize; //棧的大小 83 private int[] stack; //陣列,陣列模擬棧,資料放在該陣列 84 private int top = -1;//top表示棧頂,初始化為-1 85 86 //構造器 87 public ArrayStack2(int maxSize) { 88 this.maxSize = maxSize; 89 stack = new int[this.maxSize]; 90 } 91 //增加一個方法, 返回當前棧頂的值,不是真正的pop 92 public int pick(){ 93 return stack[top]; 94 } 95 96 //棧滿 97 public boolean isFull() { 98 return top == maxSize - 1; 99 } 100 101 //棧空 102 public boolean isEmpty() { 103 return top == -1; 104 } 105 106 //入棧-push 107 public void push(int value) { 108 //先判斷棧滿 109 if (isFull()) { 110 System.out.println("棧滿"); 111 return; 112 } 113 top++; 114 stack[top] = value; 115 } 116 117 //出棧-pop 將棧頂的資料返回 118 public int pop() { 119 //先判斷棧是否空 120 if (isEmpty()) { 121 //丟擲異常 122 throw new RuntimeException("棧空,沒有資料"); 123 } 124 int value = stack[top]; 125 top--; 126 return value; 127 } 128 129 //顯示棧的情況,遍歷時,需要從棧頂開始顯示資料 130 public void list() { 131 if (isEmpty()) { 132 System.out.println("棧空,沒有資料"); 133 return; 134 } 135 //從棧頂顯示資料 136 for (int i = top; i >= 0; i--) { 137 System.out.printf("stack[%d]=%d\n", i, stack[i]); 138 } 139 } 140 141 //擴充套件:返回運算子的優先順序,優先順序是自己確定,優先順序使用數字表示,數字越大,優先順序越高 142 public int priority(int oper){ 143 if (oper == '*' || oper == '/'){ 144 return 1; 145 }else if (oper == '+' || oper == '-'){ 146 return 0; 147 }else { 148 return -1;//假定計算式只含有+ — * / 149 } 150 151 } 152 //判斷是不是一個運算子 153 public boolean isOper(char val){ 154 return val == '+' || val == '-' || val == '*' || val == '/'; 155 } 156 //計算方法 157 public int cal(int num1,int num2,int oper){ 158 int res = 0;//res用於存放計算的結果 159 switch (oper){ 160 case'+': 161 res = num1 + num2; 162 break; 163 case'-': 164 res = num2 - num1;//注意順序 165 break; 166 case'*': 167 res = num1 * num2;//注意順序 168 break; 169 case'/': 170 res = num2 / num1;//注意順序 171 break; 172 default: 173 break; 174 } 175 return res; 176 } 177 }