该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-12-23
所谓的高手总喜欢把问题搞大了来证明自己的存在
|
|
返回顶楼 | |
发表时间:2011-12-23
情已逝 写道
canghailan 写道
在公司也做过一个类似的,需求比这个复杂,自己构建了表达式树,验证是在构建时以错误给出的,上学时编译器课写过一个mini c编译器,所以还比较熟。有了表达式树,求值就没什么问题了。如果java版本在jdk6以上就没什么必要了,应该直接ScriptEngine eval就ok了,公司还是万恶的1.4。
PS:bs投隐藏的,现在投隐藏的不知道为啥这么多,是都是牛人么???lz建议你到oschina.net社区去讨论吧,iteye现在风气已经完全败坏了,现在已经不适合讨论问题了。iteye的帖子能投隐藏到强制结帖(碰到几次了,讨论一会儿就结帖了),应该和oschina一样,花费积分才能投隐藏(不知道iteye扣不扣),看那些人还乱不乱投隐藏。
人家能求个四则运算就行了,你要给做个编译器。 我说的是我当时的情况,需求与这个不同,比较复杂,构建表达式树是我当时的一个思路。构建一个简单的表达式树只是有过编译器经验比较熟罢了,完全谈不上一个编译器。利用表达式树进行表达式求值本来就是一个很正常的做法,也没有你说的那么复杂。 情景需求不同,解决问题的方法自然会不一样。集思广益才是一个正确的讨论态度,每个人说说自己遇到的情况,自己的解决办法,能给别人提供思路,借鉴或者反思都可以。冷嘲热讽就是你讨论的态度么,至少也请看清我在说什么再给出你的结论行么?如果你有好的想法,说出来,大家一起讨论,如果你觉得没有意思大可一笑而过。 至于刚才发牢骚的确是我的不对,只不过被iteye现在的诸多隐藏弄的恼火了,说实话iteye的确越来越浮躁了。 |
|
返回顶楼 | |
发表时间:2011-12-23
这种数学表达式求值应该属于比较基础的工具吧,个人不太建议自己写
自己写的话还需要比较完善的测试,而且还要做好后续代码维护的打算,比较麻烦 可以试试JEP(其他开源的也有),10分钟就能用上 如果要写的话可以考虑后缀表达式(逆波兰表达式) http://baike.baidu.com/view/552648.htm |
|
返回顶楼 | |
发表时间:2011-12-23
如果是研究的话很不错,不过有个别人研究好的,就是bsh。
|
|
返回顶楼 | |
发表时间:2011-12-24
中缀表达式转后缀表达式,然后计算
|
|
返回顶楼 | |
发表时间:2011-12-24
10年以前上学时候帮一个mm写过的作业题,当时用c++写的,囧
我还记得当时忘记了字符串\0结尾,结果搞到半夜才调试出来 由于想表现一下当时的代码写的特标准,后来找工作凭着这个代码直接进了一家大公司,囧 |
|
返回顶楼 | |
发表时间:2011-12-24
楼主没错,楼主很倒霉,所以不发帖是王道 15个隐藏伤不起啊。。。。
|
|
返回顶楼 | |
发表时间:2011-12-24
这个确实是个很基础的问题,学校学数据结构的时候书上都有用栈来做这个的。蛮简单的!
|
|
返回顶楼 | |
发表时间:2011-12-24
我记得在腾讯笔试时做过这道题啊
贴一下自己的代码,请各位请拍(不懂编译原理,随手写的) /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package expression; /** * * @author kk */ public class Expression { private static int PLUS = 1; private static int MINOR = 2; private static int MULTIPLY = 3; private static int DIVIDE = 4; private int value; private boolean isOperator; private Expression left; private Expression right; public Expression() { this.value = 0; this.isOperator = false; this.left = null; this.right = null; } public float compute() { float result = 0; if (!isOperator) { result = (float) value; } else { switch (value) { case 1: result = left.compute() + right.compute(); break; case 2: result = left.compute() - right.compute(); break; case 3: result = left.compute() * right.compute(); break; case 4: result = left.compute() / right.compute(); break; } } return result; } public static Expression compile(String str) throws IncorrectFormulationFormatException { str = str.replaceAll("\\s*", ""); validateFormulation(str); int start = 0; int pos = 0; int length = str.length(); Expression root = null; Expression latestOperator = null; while (pos < length) { char c = str.charAt(pos); if (Character.isDigit(c)) { boolean isSingleNum = false; do { pos++; if (pos == length) { isSingleNum = true; break; } } while (Character.isDigit(str.charAt(pos))); root = new Expression(); String leftOperand = str.substring(start, pos); root.value = Integer.parseInt(leftOperand); root.isOperator = false; if (isSingleNum) { break; } start = pos; } else if (c == '(') { pos = findBracket(str, start); String subExp = str.substring(start + 1, pos); root = Expression.compile(subExp); pos++; start = pos; } else { char op = c; pos++; start = pos; Expression right = null; c = str.charAt(pos); if (c == '(') { // pos = str.indexOf(')', start); pos = findBracket(str, start); String subExp = str.substring(start + 1, pos); right = Expression.compile(subExp); pos++; } else if (Character.isDigit(c)) { pos++; while (pos < length && Character.isDigit(str.charAt(pos))) { pos++; } String rightOperand = str.substring(start, pos); right = new Expression(); right.value = Integer.parseInt(rightOperand); right.isOperator = false; } Expression operator = new Expression(); operator.isOperator = true; if (op == '+') { operator.value = Expression.PLUS; } else if (op == '-') { operator.value = Expression.MINOR; } else if (op == '*') { operator.value = Expression.MULTIPLY; } else if (op == '/') { operator.value = Expression.DIVIDE; } switch (operator.value) { case 1: case 2: operator.left = root; operator.right = right; latestOperator = operator; root = operator; break; case 3: case 4: if (latestOperator != null) { operator.left = latestOperator.right; operator.right = right; latestOperator.right = operator; latestOperator = operator; } else { operator.left = root; operator.right = right; root = operator; latestOperator = operator; } break; } start = pos; } } return root; } private static int findBracket(String str, int index) { int amount = 0; int length = str.length(); while (index < length) { if (str.charAt(index) == '(') { amount++; } if (str.charAt(index) == ')') { amount--; if (amount == 0) { return index; } } index++; } return -1; } private static void validateFormulation(String str) throws IncorrectFormulationFormatException { char c = '\0'; char prevChar = '\0'; int bracketAmount = 0; for (int i = 0; i < str.length(); i++) { c = str.charAt(i); if (i == 0) { if (c == '(') { bracketAmount++; } else if (!Character.isDigit(c)) { throw new IncorrectFormulationFormatException(c, prevChar); } } else { if (c == '(') { if (prevChar != '+' && prevChar != '-' && prevChar != '*' && prevChar != '/' && prevChar != '(') { throw new IncorrectFormulationFormatException(c, prevChar); } else { bracketAmount++; } } else if (c == ')') { if (!Character.isDigit(prevChar) && prevChar != ')') { throw new IncorrectFormulationFormatException(c, prevChar); } else { if (bracketAmount < 0) { throw new IncorrectFormulationFormatException(c, prevChar); } else { bracketAmount--; } } } else if (Character.isDigit(c)) { if (!Character.isDigit(prevChar) && prevChar != '+' && prevChar != '-' && prevChar != '*' && prevChar != '/' && prevChar != '(') { throw new IncorrectFormulationFormatException(c, prevChar); } } else if (c == '+' || c == '-' || c == '*' || c == '/') { if (!Character.isDigit(prevChar) && prevChar != ')') { throw new IncorrectFormulationFormatException(c, prevChar); } } else { throw new IncorrectFormulationFormatException(c, prevChar); } } prevChar = c; } if (bracketAmount != 0) { throw new IncorrectFormulationFormatException(c, prevChar); } } public static void main(String args[]) { String s = "(3*4+(5))*((3*((8+99)*7-6)))"; try { validateFormulation(s); } catch (Exception e) { e.printStackTrace(); } } } class IncorrectFormulationFormatException extends Exception { public IncorrectFormulationFormatException(char currentChar, char prevChar) { super("current char: " + currentChar + ", prev char: " + prevChar); } } |
|
返回顶楼 | |
发表时间:2011-12-24
参考:http://code.google.com/p/nutz/wiki/el_overview
|
|
返回顶楼 | |