栈的简单应用——四则运算(三)
2013-02-02 20:26
513 查看
待解决问题
如何计算带括号的四则运算?解决方案
一、采用符号入栈的解决方式,只是圆括号的操作方式会有所改变。圆括号的优先级最高,"("入栈后,只有遇到")"后才会出栈,并且要先弹出"("后的遗留操作符,保证"( )"中的表达式先被执行。"( )"中的加减乘除操作保持正常的栈处理方式。二、采用lisp解决问题的思路。所有的"( )"内的操作都是一样的,只不过处理的层次不一样,这时使用递归是一种很容易理解的方式。将每组"()"中的表达式看成子表达式,用相同的方法处理,将处理的结果拼接到父表达式维护的变量中。这种方式没有改变括号先行的原则。
代码实现
我采用了第二种解决方案。符号优先级的初始化
private static Map<String,Integer> priorityMap = new HashMap<String,Integer>(); private static String symPattern = ""; private Stack<String> stack = new Stack<String>(); static{ symPattern = "[+\\-*/]"; priorityMap.put("+", -1); priorityMap.put("-", -1); priorityMap.put("*", 1); priorityMap.put("/", 1); }
标准表达式输入
public String input(){ Scanner scanner = new Scanner(System.in); String str = ""; if(scanner.hasNext()){ str += scanner.next(); } System.out.println("the value of str = " + str); return str; }
校验输入的表达式是否合法
public boolean checkInput(String input) throws Exception{ char[] array = input.toCharArray(); for(int i=0;i<array.length;i++){ if(i<array.length - 1){ String prev = String.valueOf(array[i]); String next = String.valueOf(array[i+1]); if(!prev.matches("[\\(\\)\\d\\.+\\-*/]")||!next.matches("[\\(\\)\\d\\.+\\-*/]")){ throw new Exception("输入中含有非法字符,请重新输入!" ); }else if(prev.matches("[\\.+\\-*/]")&&next.matches("[\\.+\\-*/]")){ throw new Exception("输入了连续的符号!请重新输入!"); }else if(prev.matches("/")&&next.matches("0")){ throw new Exception("分母不能为零!"); } }else{ if(!String.valueOf(array[i]).matches("\\d")){ throw new Exception("非法表达式"); } } } return true; }
将中缀表达式转换为后缀表达式
public String generateSuffixExp(String input) throws Exception{ Stack<String> stack = new Stack<String>(); char[] array = input.toCharArray(); String suffix = ""; int matchIndex = 0; for(int i = 0;i < array.length;i++){ String atom = String.valueOf(array[i]); //括号先行,取得括号中的子表达式并获取其后缀表达式 if(atom.equals("(")){ //获取与左括号正确匹配的右括号索引 matchIndex = this.matchIndex(input,i); //获取该组括号的中的子表达式 String innerExp = input.substring(i+1, matchIndex); //获取子表达式的后缀表达式 atom = generateSuffixExp(innerExp); i = matchIndex; } if(atom.matches(symPattern)){ if(stack.isEmpty()){ stack.push(atom); }else{ while(!stack.isEmpty()&&priorityMap.get(stack.peek()) >= priorityMap.get(atom)){ suffix += stack.pop(); } stack.push(atom); } }else{ while((i+1 < array.length)&&!(String.valueOf(array[i+1])).matches(symPattern)){ atom += array[++i]; } //atom是十以外的数字或非某组括号中的子表达式,将atom用原括号包装成一个整体 if(atom.length() != 1&&!String.valueOf(atom.charAt(atom.length()-1)).matches(symPattern)){ atom = "(" + atom +")"; } suffix +=atom; } } while(!stack.isEmpty()){ suffix += stack.pop(); } return suffix; } public int matchIndex(String exp,int start) throws Exception{ int count = 0; for(int i = start;i < exp.length();i++){ char atom = exp.charAt(i); if(atom == '('){ count++; }else if(atom == ')'){ count--; if(count == 0){ return i; } } } throw new Exception("wrong expression!"); }
计算后缀表达式
public String resuleCompute(String suffix){ String result = ""; for(int i=0;i<suffix.length();i++){ String atom = String.valueOf(suffix.charAt(i)); if(atom.matches("\\d")){ stack.push(atom); }else if(atom.matches("\\(")){ atom = ""; while(!String.valueOf(suffix.charAt(++i)).equals(")")){ atom += String.valueOf(suffix.charAt(i)); } stack.push(atom); }else{ float a = Float.parseFloat(stack.pop()); float b = Float.parseFloat(stack.pop()); float resultExp = this.getMiddleResult(a, b, atom); stack.push(""+resultExp); } } result = stack.pop(); stack.clear(); return result; } public float getMiddleResult(float a,float b,String symbol){ if("+".equals(symbol)){ return b + a; }else if("-".equals(symbol)){ return b - a; }else if("*".equals(symbol)){ return b * a; }else{ return b / a; } }
执行程序
public static void main(String[] args) throws Exception{ Cal_Version_3 cal = new Cal_Version_3(); while(true){ String input = cal.input(); if(cal.checkInput(input)){ String suffix = cal.generateSuffixExp(input); System.out.println("the value of suffix is " + suffix); System.out.println(cal.resuleCompute(suffix)); } } }
执行结果
9+(3-1)*3+10/2 the value of str = 9+(3-1)*3+10/2 the value of suffix is 931-3*+(10)2/+ 20.0 2.5+(2*(2.5+2))+2.5 the value of str = 2.5+(2*(2.5+2))+2.5 the value of suffix is (2.5)2(2.5)2+*+(2.5)+ 14.0
结果讨论
程序达到了预期的效果,但是还有很多工作要做,但基本目的已经达到了,已经了解了java实现表达式的四则运算。相关文章推荐
- 运算符重载简单应用之分数四则运算
- 栈的简单应用——四则运算(一)
- winform程序之comboBox控件应用四则运算(简单)
- 栈的应用:简单加减乘除四则运算——2018/01/06思考
- 栈的应用--简单四则运算
- PHP实现最简单的聊天室应用
- android基础学习之wifi的简单应用
- Linux 系统启动流程及 Grub 简单应用
- KMP简单应用
- Spring AOP原理及简单应用
- 宏函数中#, ##及参数的简单应用
- redis在Java web项目的简单应用
- Android:使用fragment(碎片)—让你的应用更灵活(一)简单运用
- 【iOS 初见】第一个简单的 iOS 应用
- grub的简单应用与配置
- jquery.query.js 插件(示例及简单应用)
- 素数的简单应用
- 简单应用函数
- C# switch 语句的简单应用