java堆栈四则运算_Java实现四则运算,使用堆栈,检查语法

1 importjava.util.HashMap;2 importjava.util.Map;3 importjava.util.Stack;4

5 public classFunctionStack {6

7 private MapoptLevel;8 private boolean nextIsOpt = false;9 private boolean debug = false;10 private int debug_len = 3;11

12 public FunctionStack setDebugLen(intlen) {13 this.debug_len =len;14 return this;15 }16

17 public FunctionStack setDebug(booleandebug) {18 this.debug =debug;19 return this;20 }21

22 private voidprintln(Object obj) {23 if(debug) {24 System.out.println(obj);25 }26 }27

28 publicFunctionStack() {29 optLevel = new HashMap();30 optLevel.put("(", 1);31 optLevel.put("+", 2);32 optLevel.put("-", 2);33 optLevel.put("*", 3);34 optLevel.put("/", 3);35 optLevel.put(")", 4);36 }37

38 public static voidmain(String[] args) {39

40

41 FunctionStack fs = newFunctionStack();42 fs.setDebug(true).setDebugLen(5);43 String fun = " 1 + 2 * 3 / 4 ";44 try{45 float res =fs.execute(fun);46 System.out.println("结果为:" +res);47 } catch(FunctionStackException e) {48 System.out.println(e.getMessage());49 }50 System.out.println("结束.");51 }52

53 /**

54 *55 *@paramfun56 *@return

57 *@throwsFunctionStackException58 */

59 public float execute(String fun) throwsFunctionStackException {60 this.clear();61 //TODO Auto-generated method stub

62 if (fun == null || fun.trim().length() == 0) {63 throw new FunctionStackException("表达式不能为空;");64 }65 //创建操作符堆栈和操作数堆栈

66 Stack opt = new Stack();67 Stack num = new Stack();68 //扫描整个表达式69 //point记录上一个扫描点

70 int point = 0;71 for (int i = 0; i < fun.length(); i++) {72 String scanOpt = fun.charAt(i) + "";73 if (scanOpt.equals("(")) {74 //发现左括号,压入栈75 //检查是否为空的括号

76 int right = fun.indexOf(')', i);77 if (right < 0) {78 //如果没有找到右括号

79 throw newFunctionStackException(fun80 + "\n语法错误:"

81 + "缺少右括号与之对应:"

82 + fun.substring(Math.max(point - debug_len, 0),83 Math.min(i +debug_len, fun.length())));84 } else{85 //找到右括号,检查是否为空括号

86 if (fun.substring(i + 1, right).trim().length() == 0) {87 throw newFunctionStackException(fun88 + "\n语法错误:"

89 + "括号中内容不可为空:"

90 + fun.substring(Math.max(point - debug_len, 0),91 Math.min(i +debug_len, fun.length())));92 }93 }94 //检查语法

95 String num_before_opt =fun.substring(point, i).trim();96 if (num_before_opt.length() != 0) {97 throw newFunctionStackException(fun98 + "\n语法错误:"

99 + "括号前缺少操作符:"

100 + fun.substring(Math.max(point - debug_len, 0),101 Math.min(i +debug_len, fun.length())));102 }103 //将左括号压入栈

104 println("↓压栈:" + fun.substring(i, i + 1));105 opt.push(fun.substring(i, i + 1));106 //记录扫描点

107 point = i + 1;108 } else if (scanOpt.equals(")")) {109 //发现右括号,取出栈,直到取出左括号

110 println("---计算括号开始:");111 //将括号前的数值取出

112 pushFloatStack(fun, num, point, i);113 //记录下一个是操作符

114 nextIsOpt = true;115 //检查前一个操作符是否为空

116 if(opt.empty()) {117 throw newFunctionStackException(fun118 + "\n语法错误:"

119 + "缺少左括号与之对应:"

120 + fun.substring(Math.max(point - debug_len, 0),121 Math.min(i +debug_len, fun.length())));122 }123 //取出前一个操作符

124 String optpop =opt.pop();125 println("↑↑出栈:" +optpop);126 //取出栈,直到取出左括号

127 while (!optpop.equals("(")) {128 //若取出的操作符不是左括号,执行运算;

129 calculator(optpop, num);130 if(opt.empty()) {131 throw newFunctionStackException(fun132 + "\n语法错误:"

133 + "缺少左括号与之对应:"

134 + fun.substring(Math.max(point - debug_len, 0),135 Math.min(i +debug_len, fun.length())));136 }137 optpop =opt.pop();138 println("↑↑出栈:" +optpop);139 }140

141 //记录扫描点

142 point = i + 1;143 println("---计算括号结束:");144 } else if (optLevel.get(scanOpt) != null) {145 if (scanOpt.equals("-") || scanOpt.equals("+")) {146 //如果是减号,可能是一个负号

147 if (fun.substring(point, i).trim().replaceAll("-", "")148 .replaceAll("\\+", "").trim().length() == 0) {149 //如果减号前没有操作数,视此减号为负号,point不移动,-也不压入堆栈

150 continue;151 }152 }153 //发现非括号的操作符,查看栈顶操作符优先级,选择计算or压栈154 //获取操作数,并检查语法

155 pushFloatStack(fun, num, point, i);156 //比较优先级,将栈顶优先级高的先计算

157 if (!opt.empty()) {158 //获取栈顶操作符,不取出

159 String optpop =opt.peek();160 //取栈计算,直到栈顶操作符优先级小于scanOpt

161 while (optLevel.get(optpop) >=optLevel.get(scanOpt)) {162 calculator(optpop, num);163 optpop =opt.pop();164 println("↑↑出栈:" +optpop);165 if(opt.empty()) {166 //如果操作符取空了则退出

167 break;168 }169 optpop =opt.peek();170 }171 }172 //压入操作符

173 println("↓压栈:" +scanOpt);174 opt.push(scanOpt);175 //记录扫描点

176 point = i + 1;177 } else if (scanOpt.equals("=")) {178 //发现=号,取栈计算总结果,并提前结束循环179 //获取操作数,并检查语法

180 pushFloatStack(fun, num, point, i);181 //取栈计算直到结束

182 while (!opt.empty()) {183 String optpop =opt.pop();184 println("↑↑出栈:" +optpop);185 calculator(optpop, num);186 }187 returngetResult(num);188 }189

190 }191

192 //表达式结束193 //获取操作数,并检查语法

194 pushFloatStack(fun, num, point, fun.length());195 //取栈计算直到结束

196 while (!opt.empty()) {197 String optpop =opt.pop();198 println("↑↑出栈:" +optpop);199 calculator(optpop, num);200 }201 returngetResult(num);202 }203

204 private voidclear() {205 //TODO Auto-generated method stub

206 nextIsOpt = false;207 }208

209 private float getResult(Stacknum) {210 //TODO Auto-generated method stub

211 Float res =num.pop();212 if(num.empty()) {213 returnres;214 } else{215 throw new FunctionStackException("计算错误,堆栈中还有数据;");216 }217 }218

219 /**

220 * 将操作符i前的操作数解析,并压入堆栈221 *222 *@paramfun223 *@paramnum224 *@parampoint225 * 操作数起点226 *@parami227 * 操作符位置,即操作数终点228 */

229 private void pushFloatStack(String fun, Stack num, int point, inti) {230 String num_before_opt =fun.substring(point, i).trim();231 if (num_before_opt.length() == 0) {232 //没有操作数

233 if(nextIsOpt) {234

235 //应该没有操作数,(即此处本应只有操作符,没有操作数)

236 nextIsOpt = false;237 return;238 } else{239 //应该有操作数

240 throw newFunctionStackException(fun241 + "\n语法错误:"

242 + "缺少操作数:"

243 + fun.substring(Math.max(point - debug_len, 0),244 Math.min(i +debug_len, fun.length())));245 }246 } else{247 //有操作数

248 if(nextIsOpt) {249 //应该没有操作数

250 throw newFunctionStackException(fun251 + "\n语法错误:"

252 + "缺少操作符:"

253 + fun.substring(Math.max(point - debug_len, 0),254 Math.min(i +debug_len, fun.length())));255 } else{256 //应该有操作数

257 try{258 //去除操作数中间的空格、回车、制表符

259 num_before_opt = num_before_opt.replaceAll(" ", "");260 num_before_opt = num_before_opt.replaceAll("\t", "");261 num_before_opt = num_before_opt.replaceAll("\n", "");262 Float scannum =Float.parseFloat(num_before_opt);263 println("↓压栈:" +scannum);264 num.push(scannum);265 } catch(NumberFormatException e) {266 throw new FunctionStackException(fun + "\n语法错误:"

267 + "无法识别的数值:" +num_before_opt);268 }269 }270 }271 }272

273 /**

274 *275 *@paramoptpop276 * 运算符277 */

278 private void calculator(String optpop, Stacknum) {279 //TODO Auto-generated method stub

280 Float pop2 =num.pop();281 println("↑↑出栈:" +pop2);282 Float pop1 =num.pop();283 println("↑↑出栈:" +pop1);284 println("--------计算 " + pop1 + optpop +pop2);285 if (optpop.equals("+")) {286 println("↓压栈:" + (pop1 +pop2));287 num.push(pop1 +pop2);288 } else if (optpop.equals("-")) {289 println("↓压栈:" + (pop1 -pop2));290 num.push(pop1 -pop2);291 } else if (optpop.equals("*")) {292 println("↓压栈:" + (pop1 *pop2));293 num.push(pop1 *pop2);294 } else if (optpop.equals("/")) {295 if (pop2 == 0) {296 throw new FunctionStackException("语法错误:" + "除数不可以为零:" +pop2);297 }298 println("↓压栈:" + (pop1 /pop2));299 num.push(pop1 /pop2);300 } else if (optpop.equals("(")) {301 throw new FunctionStackException("语法错误:" + "缺少右括号与之对应:" +optpop);302 } else{303 throw new FunctionStackException("语法错误:" + "错误的操作符:" +optpop);304 }305

306 }307

308 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值