本次课程学习四则运算的加强
1 package com.baidu; 2 3 4 import java.text.NumberFormat; 5 import java.util.ArrayList; 6 import java.util.Stack; 7 8 9 public class CalculateStack { 10 static private CalculateStack cl = new CalculateStack(); 11 private Stack<String> num = new Stack<>(); 12 private Stack<Character> opStack = new Stack<>(); 13 private RuleTable ruleTable = new RuleTable(); 14 private double getCalculateNumber(double num1,Character op,double num2) { 15 16 double res = 0; 17 switch(op.charValue()) { 18 19 case '+':{ 20 res = num1 + num2; 21 }break; 22 23 case '-':{ 24 res = num1 - num2; 25 }break; 26 case 'x':{ 27 28 res = num1 * num2; 29 }break; 30 case '/':{ 31 32 res = num1 / num2; 33 }break; 34 35 } 36 return res; 37 } 38 private char serchOp(char ch, char top) { 39 40 //System.out.println("ch:"+ch+" top:"+top); 41 for(Rule rule:this.ruleTable.getRuleList()) { 42 if(top == rule.ch1&&rule.ch2 == ch) { 43 //System.out.println("从表中找到:关系为top" + rule.equ +"ch"); 44 return rule.equ; 45 } 46 } 47 return '@'; 48 } 49 public String Calculate(String strSource,int Accuracy) { 50 boolean ret = true; 51 52 Object[] ch1 = this.strToOpStr(strSource); 53 for(int i = 0; i < ch1.length; i++) { 54 if(ch1[i].toString().isEmpty()) 55 break; 56 if(!this.isOperator(ch1[i].toString())) { 57 this.num.push(ch1[i].toString()); 58 59 }else { 60 //System.out.println(ch); 61 switch(this.serchOp(ch1[i].toString().charAt(0),this.opStack.lastElement())){ 62 case '<':{ 63 64 this.opStack.push(new Character(ch1[i].toString().charAt(0))); 65 //System.out.println(ch1[i].charAt(0)+"压入操作符"); 66 }break; 67 case '>': { 68 double num2 = Double.valueOf(this.num.pop()); 69 70 double num1 = Double.valueOf(this.num.pop()); 71 72 char op = this.opStack.pop(); 73 //System.out.println(ch1[i].charAt(0)+"弹出操作符"); 74 this.num.push(new Double(this.getCalculateNumber(num1, op, num2)).toString()); 75 i--; 76 }break; 77 case '@': { 78 System.out.println("不合法的表达式"); 79 ret = false; 80 }break; 81 82 case '=': { 83 //去括号,#号 84 this.opStack.pop(); 85 //System.out.println(ch1[i].charAt(0)+"弹出操作符"); 86 }break; 87 } 88 } 89 } 90 NumberFormat nb = NumberFormat.getNumberInstance(); 91 nb.setMinimumFractionDigits(Accuracy); 92 double res = Double.valueOf(this.num.pop()); 93 94 return ret?nb.format(res):null; 95 } 96 private boolean CheckeStr(String strSource) { 97 98 char[] chSource = strSource.toCharArray(); 99 for(int i = 1; i < chSource.length; i++) { 100 if((chSource[i-1] == '('||chSource[i-1] == ')')&&!this.isOperater(chSource[i])) { 101 return false; 102 }else if((chSource[i] == '('||chSource[i] == ')')&&!this.isOperater(chSource[i-1])) { 103 return false; 104 } 105 } 106 return true; 107 } 108 109 110 private CalculateStack() { 111 this.num.push(new Integer(0).toString()); 112 this.opStack.push(new Character('#')); 113 } 114 private boolean isOperator(String str) { 115 116 if(str.toCharArray().length == 1) { 117 for(char ch:RuleTable.op) { 118 if(ch == str.toCharArray()[0]) 119 return true; 120 } 121 }else if(str.isEmpty()){ 122 return false; 123 }else { 124 return false; 125 } 126 return false; 127 } 128 129 //此方法实现把操作符和操作数解析为字符串数组 130 private Object[] strToOpStr(String strSource) { 131 int num = 0; 132 boolean isOp = true; 133 String[] retStr = new String[100]; 134 135 char[] ch = strSource.toCharArray(); 136 for(char ch1:ch) { 137 if(this.isOperater(ch1)&&num == 0&&!isOp) { 138 num++; 139 retStr[num++] = new String(new Character(ch1).toString()); 140 isOp = true; 141 }else if(this.isOperater(ch1)&&num == 0&&isOp) { 142 retStr[num++] = new String(new Character(ch1).toString()); 143 isOp = true; 144 }else if(this.isOperater(ch1)&&num != 0){ 145 if(!isOp) 146 num++; 147 retStr[num++] = new String(new Character(ch1).toString()); 148 isOp = true; 149 }else if(!this.isOperater(ch1)&&num != 0){ 150 if(retStr[num] == null) 151 retStr[num] = new String(new Character(ch1).toString()); 152 else { 153 retStr[num] += ch1; 154 } 155 156 isOp = false; 157 }else if(!this.isOperater(ch1)&&num == 0) { 158 159 if(isOp) { 160 //System.out.println("opchar:" + ch1+"op:"+isOp+"num:"+num); 161 retStr[num] = new String(new Character(ch1).toString()); 162 //System.out.println("opchar:" + ch1+"op:"+isOp+"num:"+num+"rerStr:"+retStr[num]); 163 }else { 164 retStr[num] += ch1; 165 //System.out.println("opchar:" + ch1+"op:"+isOp+"num:"+0+"rerStr:"+retStr[0]); 166 } 167 isOp = false; 168 } 169 } 170 ArrayList<String> list = new ArrayList<>(); 171 for(int i = 0; i < retStr.length; i++) { 172 if(retStr[i] != null) { 173 list.add(retStr[i]); 174 } 175 } 176 list.add(list.size(),"#"); 177 return list.toArray(); 178 } 179 private boolean isOperater(char ch) { 180 181 for(char ch1:RuleTable.op) { 182 if(ch == ch1) 183 return true; 184 } 185 return false; 186 } 187 //demo 188 public static void main(String[] args) { 189 190 CalculateStack cl = CalculateStack.getCalculateInstance(); 191 System.out.println(cl.Calculate("(3x4)/1.11-3x45+12-12333", 1)); 192 193 } 194 static public CalculateStack getCalculateInstance() { 195 return cl; 196 } 197 } 198 199 200 package com.baidu; 201 202 import java.util.ArrayList; 203 204 public class RuleTable { 205 static public char[] op = { 206 '+', 207 '-', 208 'x', 209 '/', 210 '(', 211 ')', 212 '#' 213 }; 214 private int[][] re = { 215 {1,1,-1,-1,-1,1,1}, 216 {1,1,-1,-1,-1,1,1}, 217 {1,1,1,1,-1,1,1}, 218 {1,1,1,1,-1,1,1}, 219 {-1,-1,-1,-1,-1,0,2}, 220 {1,1,1,1,-2,1,1}, 221 {-1,-1,-1,-1,-1,2,0}, 222 }; 223 private ArrayList<Rule> ruleList = new ArrayList<>(); 224 225 public ArrayList<Rule> getRuleList() { 226 return this.ruleList; 227 } 228 public RuleTable() { 229 230 for(int i = 0; i < op.length; i++) { 231 for(int j = 0; j < op.length; j++) { 232 Rule rule = new Rule(); 233 rule.ch1 = op[i]; 234 rule.ch2 = op[j]; 235 if(re[i][j] == 1) { 236 rule.equ = '>'; 237 }else if(re[i][j] == -1) { 238 rule.equ = '<'; 239 }else if(re[i][j] == 0) { 240 rule.equ = '='; 241 }else { 242 rule.equ = '@'; 243 } 244 245 ruleList.add(rule); 246 } 247 } 248 } 249 } 250 class Rule { 251 char ch1 = 0; 252 char ch2 = 0; 253 char equ = 0; 254 }