package com.xuz.csdn.june16;import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class ScriptEngineTest { public static void main(String[] args) { ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine se = sem.getEngineByName("js"); try { System.out.println(se.eval("1+2*(3+4)").toString()); } catch (ScriptException e) { e.printStackTrace(); } }}
import java.util.LinkedList; import java.util.Map; public class ExpressionUtil { public String getPostfixExp(String expression,Map<String,Integer> priorities){ LinkedList<String> opStack = new LinkedList<String>(); StringBuffer result = new StringBuffer();
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptEngineTest { public static void main(String[] args) {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByName("js");
try {
System.out.println(se.eval("1+2*(3+4)").toString());
} catch (ScriptException e) {
e.printStackTrace();
}
}}
import java.util.LinkedList;
import java.util.Map;
public class ExpressionUtil { public String getPostfixExp(String expression,Map<String,Integer> priorities){
LinkedList<String> opStack = new LinkedList<String>();
StringBuffer result = new StringBuffer();
for(Character c: expression.toCharArray()){
String cs = c.toString();
if(priorities.containsKey(cs)){
if("(".equals(cs)){
opStack.offerLast(cs);
}else if(")".equals(cs)){
while(opStack.size()>0){
String op = opStack.pollLast();
if(!"(".equals(op)){
result.append(op);
}
}
}else{
String opString = opStack.peekLast();
if(opStack.size()>0 && !"(".equals(opString)){
Integer current = priorities.get(cs);
Integer stackLast = priorities.get(opString);
if(current<=stackLast){
result.append(opStack.pollLast());
}
}
opStack.offerLast(cs);
}
}else{
result.append(cs);
}
System.out.println(opStack.toString()+":"+result);
}
while(opStack.size()>0){
result.append(opStack.removeLast());
}
return result.toString();
}
public Double getValueByPostfix(String postfix,Map<String,Double> dict,Map<String,Integer> priorities,String... e){
LinkedList<Double> numStack = new LinkedList<Double>();
StringBuffer tempDield = new StringBuffer();
for(Character c: postfix.toCharArray()){
Double temp = null;
if(priorities.containsKey(c.toString())){
Double right = numStack.pollLast();
Double left = numStack.pollLast();
if("+".equals(c.toString())){
temp = left+right;
}else if("-".equals(c.toString())){
temp = left-right;
}else if("*".equals(c.toString())){
temp = left*right;
}else if("/".equals(c.toString())){
temp = left/right;
}
System.out.println(temp+"="+left+c.toString()+right);
}else{
if(e.length==2){
if(e[0].equals(c.toString())){
tempDield.append(c.toString());
continue;
}else if(e[1].equals(c.toString())){
tempDield.append(c.toString());
temp = dict.get(tempDield.toString());
tempDield = new StringBuffer();
}else if(tempDield.length()>0 && !e[1].equals(c.toString())){
tempDield.append(c.toString());
continue;
}
}else{
temp = dict.get(c.toString());
}
System.out.println(temp);
}
numStack.offerLast(temp);
}
return numStack.getFirst();
}
public Double getValueByExpression(String expression,Map<String,Double> dict,Map<String,Integer> priorities,String... e){
String postfix = getPostfixExp(expression,priorities);
return getValueByPostfix(postfix,dict,priorities,e);
}
}
Junit测试类:
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;public class TestExpressionUtil {
Map<String,Integer> priorities = null;
Map<String,Double> dict = null;
Map<String,Double> realDict = null;
@Before
public void setUp() throws Exception {
priorities = new HashMap<String,Integer>();
priorities.put("(", 9);
priorities.put(")", 9);
priorities.put("/", 8);
priorities.put("*", 8);
priorities.put("+", 7);
priorities.put("-", 7);
dict = new HashMap<String,Double>();
dict.put("a", 2.0);
dict.put("b", 1.0);
dict.put("c", 5.0);
dict.put("d", 3.0);
dict.put("e", 1.0);
dict.put("f", 4.0);
dict.put("g", 10.0);
dict.put("h", 5.0);
dict.put("i", 6.0);
realDict = new HashMap<String,Double>();
realDict.put("{a}", 1.0);
realDict.put("{b}", 2.0);
realDict.put("{c}", 3.0);
realDict.put("{d}", 4.0);
realDict.put("{e}", 5.0);
realDict.put("{f}", 6.0);
realDict.put("{g}", 7.0);
realDict.put("{h}", 8.0);
realDict.put("{i}", 9.0);
} @After
public void tearDown() throws Exception {
} @Test
public void testGetPostfixExp() {
String expression = "A+B*(C+D)-E/F";//"(a-b)*c+d-e/f";
String output = "ABCD+*+EF/-";//"ab-c*d+ef/-";
assertEquals(
output,
new ExpressionUtil().getPostfixExp(
expression,
priorities
)
);
}
@Test
public void testGetValueByPostfix(){
String postfix ="ab-c*d+ef/-"; //(a-b)*c+d-e/f = (2-1)*5+3-1/4 = 7.75
//String postfix ="badf+*+ih/-"; //1234+*+65/- = 13.8
assertEquals(
new Double(7.75),
new ExpressionUtil().getValueByPostfix(
postfix,
dict,
priorities)
);
} @Test
public void testGetValueByExpression(){
String expression = "a+b+c+d*(g-f)";// 2+1+5+3*(10-4)
assertEquals(
new Double(26.0),
new ExpressionUtil().getValueByExpression(
expression,
dict,
priorities)
);
}
@Test
public void testGetValueByExpressionX(){
//String expression = "{a}+{b}+{c}+{d}*({f}-{e})";// 1+2+3+4*(6-5) =10.0
String expression = "({c}-{a}+{b})*({e}-{d})+{f}-{i}/{c}"; //(3-1+2)*(5-4)+6-9/3 =7
assertEquals(
new Double(7.0),
new ExpressionUtil().getValueByExpression(
expression,
realDict,
priorities,
new String[]{"{","}"})
);
}
}
不过要jdk6才支持,1.5要另外加jar包
另外使用beanshell也可以
然后是逆波兰,
你也可以用ANTLR一类的工具,生成一个简单的语法解析器。
我有一个项目中有这个东西的实现。
http://spiniper-commons-tool.googlecode.com/svn/trunk/ spiniper-commons-tool-read-only
用svn下载这个项目即可
攒一个、、、
我有一个方法不知道行不行你自己建立一个包,里面是
D:\Program Files\Java\jdk1.6.0_05\src\javax\script(把这里面的类都复制到你自己建立的包下)
中用到的所有类和接口让后你就可以用4楼的方法了
btw: 中缀表达式转后缀表达式,怎么转?
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test{
public static void main(String[] args){
String result = compute("-2/5*(-5-5)*-6-5");
System.out.println(result);
} public static String compute(String expression){
expression = "(" + expression + ")";
String regex = "(.*?)(\\([^()]+\\))(.*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(expression); while(matcher.find()){
expression = matcher.group(1) + compute1(matcher.group(2)) + matcher.group(3);
matcher = pattern.matcher(expression);
//System.out.println(expression);
} return expression;
} private static String compute1(String expression){
/*
计算没有包含括号的情况下的结果
*/
expression = expression.replaceAll("[( )]","");
String regex = "^(.*?)(\\d+(?:\\.\\d+)?)([/*])(-?\\d+(?:\\.\\d+)?)(.*)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(expression); double value1 = 0.0;
double value2 = 0.0; String temp = null; while(matcher.find()){
value1 = Double.valueOf(matcher.group(2));
value2 = Double.valueOf(matcher.group(4));
if(matcher.group(3).equals("*")){
temp = (value1 * value2) + "";
}else{
temp = (value1 / value2) + "";
}
expression = matcher.group(1) + temp + matcher.group(5);
expression = expression.replaceAll("--","+");
matcher = pattern.matcher(expression);
} //System.out.println(expression); regex = "^(.*?)((?:(?=[-+*/])-)?\\d+(?:\\.\\d+)?)([-+])(-?\\d+(?:\\.\\d+)?)(.*)";
pattern = Pattern.compile(regex);
matcher = pattern.matcher(expression); while(matcher.find()){
value1 = Double.valueOf(matcher.group(2));
value2 = Double.valueOf(matcher.group(4)); if(matcher.group(3).equals("+")){
temp = (value1 + value2) + "";
}else{
temp = (value1 - value2) + "";
} expression = matcher.group(1) + temp + matcher.group(5);
matcher = pattern.matcher(expression);
} expression = expression.replaceAll("\\+",""); return expression;
}
}
有sin,E 等特殊符号没??
import java.io.*;import java.util.*;public class Test { private ArrayList expression = new ArrayList();// 存储中序表达式 private ArrayList right = new ArrayList();// 存储右序表达式 private String result;// 结果 // 依据输入信息创建对象,将数值与操作符放入ArrayList中 public Test(String input) { StringTokenizer st = new StringTokenizer(input, "+-*/()", true); while (st.hasMoreElements()) { expression.add(st.nextToken()); } } // 将中序表达式转换为右序表达式 private void toRight()
{ Stacks aStack = new Stacks(); String operator; int position = 0; while (true) { if (Calculate.isOperator((String) expression.get(position))) { if (aStack.top == -1|| ((String) expression.get(position)).equals("("))
{ aStack.push(expression.get(position)); } else { if (((String) expression.get(position)).equals(")"))
{ if (!((String) aStack.top()).equals("("))
{ operator = (String) aStack.pop(); right.add(operator); } } else { if (Calculate.priority((String) expression.get(position)) <= Calculate.priority((String) aStack.top())&& aStack.top != -1)
{ operator = (String) aStack.pop(); if (!operator.equals("(")) right.add(operator); } aStack.push(expression.get(position)); } } }
else right.add(expression.get(position)); position++; if (position >= expression.size()) break; }// Iterator itdt=this.right.iterator();
// while(itdt.hasNext())
// {
// System.out.print((String)itdt.next()+" ");
// }
// System.out.println("");
while (aStack.top != -1) {
operator = (String) aStack.pop();
// System.out.print(operator+"ddd");
if(!operator.equals("("))
right.add(operator); }
} // 对右序表达式进行求值 private void getResult() { this.toRight();
Iterator itt=this.right.iterator();
while(itt.hasNext())
{
System.out.print((String)itt.next()+" ");
}
System.out.println("");
Stacks aStack = new Stacks(); String op1, op2, is = null; Iterator it = right.iterator(); while (it.hasNext()) { is = (String) it.next(); if (Calculate.isOperator(is)) { op1 = (String) aStack.pop(); op2 = (String) aStack.pop(); aStack.push(Calculate.twoResult(is, op1, op2)); } else aStack.push(is); } result = (String) aStack.pop(); it = expression.iterator(); while (it.hasNext()) { System.out.print((String) it.next()); } System.out.println("=" + result); } public static void main(String avg[]) { try { System.out.println("Input a expression:"); BufferedReader is = new BufferedReader(new InputStreamReader(System.in)); for (;;) { String input = new String(); input = is.readLine().trim(); if (input.equals("q")) break; else { Test boya = new Test(input); boya.getResult(); } System.out.println("Input another expression or input 'q' to quit:"); } is.close(); } catch (IOException e) { System.out.println("Wrong input!!!"); } }}class Calculate { // 判断是否为操作符号 public static boolean isOperator(String operator) { if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/") || operator.equals("(") || operator.equals(")")) return true; else return false; } // 设置操作符号的优先级别 public static int priority(String operator) { if (operator.equals("+") || operator.equals("-") || operator.equals("(")) return 1; else if (operator.equals("*") || operator.equals("/")) return 2; else return 0; } // 做2值之间的计算 public static String twoResult(String operator, String a, String b) { try { String op = operator; String rs = new String(); double x = Double.parseDouble(b); double y = Double.parseDouble(a); double z = 0; if (op.equals("+")) z = x + y; else if (op.equals("-")) z = x - y; else if (op.equals("*")) z = x * y; else if (op.equals("/")) z = x / y; else z = 0; return rs + z; } catch (NumberFormatException e) { System.out.println("input has something wrong!"); return "Error"; } }}class Stacks { private LinkedList list = new LinkedList(); int top = -1; public void push(Object value) { top++; list.addFirst(value); } public Object pop() { Object temp = list.getFirst(); top--; list.removeFirst(); return temp; } public Object top() { return list.getFirst(); }}
//递归,250行~
public class Main { /**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
//System.out.println("" + computeTest("(2+1)-2*1/3"));
String str = "(2+1)-2*1/3";
System.out.println(computeTest(str));
} static int computeTest(final String str) {
if (str.charAt(0) == '(' && str.charAt(str.length() - 1) == ')') {
return computeTest(str.substring(1, str.length() - 1));
} ///如果是数字则反回
try {
return Integer.parseInt(str);
} catch (NumberFormatException nfe) {
} byte fh1 = 0, fh2 = 0;//符号
int num1 = 0, num2 = 0, num = 0;//数字 ///is_type为当前计算式的类型
/// 0 空式子
/// 1 只有一个数字
/// 2 数字 + 运算符号
/// 3 数字 + 运算符号(+ -号)+ 数字
/// 4 数字 + 运算符号(+ -号)+ 数字 + 运算符号
byte is_type = 0; String ns = str;
while (!ns.isEmpty()) {//没扫描完则循环
switch (getType(ns)) {//当前遇到的类型
// case 0:
// break;
case 1://数字
num = getInt(ns);//得到数字值
ns = ns.substring(getIntSize(ns));//扫描位置前移
if (is_type == 0) {
num1 = num;
is_type = 1;
} else if (is_type == 2) {
if (fh1 == 4) {
num1 *= num;
is_type = 0;
} else if (fh1 == 5) {
num1 /= num;
is_type = 0;
} else {
num2 = num;
is_type = 3;
}
} else if (is_type == 4) {
if (fh2 == 4) {
num2 *= num;
is_type = 3;
} else if (fh2 == 5) {
num2 /= num;
is_type = 3;
}
}
break;
case 2://+
ns = ns.substring(1);
if (is_type == 0) {
num1 = 0;
fh1 = 2;
is_type = 2;
} else if (is_type == 1) {
fh1 = 2;
is_type = 2;
} else if (is_type == 3) {
if (fh1 == 2) {
num1 += num2;
}
if (fh1 == 3) {
num1 -= num2;
}
fh1 = 2;
is_type = 2;
}
break;
case 3://-
ns = ns.substring(1);
if (is_type == 0) {
num1 = 0;
fh1 = 3;
is_type = 2;
} else if (is_type == 1) {
fh1 = 3;
is_type = 2;
} else if (is_type == 3) {
if (fh1 == 2) {
num1 += num2;
}
if (fh1 == 3) {
num1 -= num2;
}
fh1 = 3;
is_type = 2;
}
break;
case 4://*
ns = ns.substring(1);
if (is_type == 1) {
fh1 = 4;
is_type = 2;
} else if (is_type == 3) {
fh2 = 4;
is_type = 4;
}
break;
case 5:// /
ns = ns.substring(1);
if (is_type == 1) {
fh1 = 5;
is_type = 2;
} else if (is_type == 3) {
fh2 = 5;
is_type = 4;
}
break;
case 6://( 和上面遇到数字一样
int post = getStringPost(ns);
num = computeTest(ns.substring(0, post));//递归括号内的 算术运算子式
ns = ns.substring(post);
if (is_type == 0) {
num1 = num;
is_type = 1;
} else if (is_type == 2) {
if (fh1 == 4) {
num1 *= num;
is_type = 0;
} else if (fh1 == 5) {
num1 /= num;
is_type = 0;
} else {
num2 = num;
is_type = 3;
}
} else if (is_type == 4) {
if (fh2 == 4) {
num2 *= num;
is_type = 3;
} else if (fh2 == 5) {
num2 /= num;
is_type = 3;
}
}
break;
// case 7://)
// break;
}
}
if (is_type == 1) {//最后剩一个数字
return num1;
}
if (is_type == 3) {//最后剩 数字 运算符号 数字
switch (fh1) {
case 2:
return num1 + num2;
case 3:
return num1 - num2;
case 4:
return num1 * num2;
case 5:
return num1 / num2;
}
}
throw new NumberFormatException();
} /**得到配对的括号的串的结束位置*/
static int getStringPost(String str) {
int post = 1;//当前位置
int count = 1;//左括号数
int pmax = str.length();//总长
while (post <= pmax) {
if (str.charAt(post) == ')') {
count--;
if (count == 0) {//如果找到配对的括号则返回
return post + 1;
}
} else if (str.charAt(post) == '(') {
count++;
}
post++;
}
return -1;
} /**得到类型*/
static int getType(String str) {
char c = str.charAt(0);
if (c <= '9' && c >= '0') {
return 1;
} else if (c == '+') {
return 2;
} else if (c == '-') {
return 3;
} else if (c == '*') {
return 4;
} else if (c == '/') {
return 5;
} else if (c == '(') {
return 6;
} else if (c == ')') {
return 7;
}
return 0;
} /**得到当前整数*/
static int getInt(String str) {
int count = 0;
for (int i = 0, im = str.length(); i < im; i++) {
if (str.charAt(i) < '0' || str.charAt(i) > '9') {
break;
}
count++;
}
return Integer.parseInt(str.substring(0, count));
} /**得到当前整数位数*/
static int getIntSize(String str) {
int count = 0;
for (int i = 0, im = str.length(); i < im; i++) {
if (str.charAt(i) < '0' || str.charAt(i) > '9') {
break;
}
count++;
}
return count;
}
}
public class Main { public static void main(String[] args) {
String str = "(2+1)-2*1/3";
System.out.println(computeTest(str));
} static int computeTest(final String str) {
if (str.charAt(0) == '(' && str.charAt(str.length() - 1) == ')') {
return computeTest(str.substring(1, str.length() - 1));
} ///如果是数字则反回
try {
return Integer.parseInt(str);
} catch (NumberFormatException nfe) {
} //当前计算式:数字1 + 运算符1 + 数字2 +运算符2 + 临时数
// 当遇到括号时 把括号 以及括号内的 子 式子当成一个数字,用递归把子式子计算出值
//运算符1为 *,/时,直接计算 (数字1 + 运算符1 + 数字2)的值,将值赋给 数字1
//当 数字1 + 运算符1 + 数字2 +运算符2 + 临时数 时,直接计算 (数字2 +运算符2 + 临时数)
// 将值赋给 数字2
int fh1 = 0, fh2 = 0;//符号
int num1 = 0, num2 = 0, num = 0;//数字1,数字2,临时数 ///is_type为当前计算式的类型
/// 0 空式子
/// 1 只有一个数字
/// 2 数字 + 运算符号
/// 3 数字 + 运算符号(+ -号)+ 数字
/// 4 数字 + 运算符号(+ -号)+ 数字 + 运算符号
byte is_type = 0; boolean flag, flag2, flag3;
String ns = str;
while (!ns.isEmpty()) {//没扫描完则循环
flag = flag2 = flag3 = true;
switch (getType(ns)) {//当前遇到的类型
case 6://( 子式子进入递归
flag = false;
int post = getStringPost(ns);//得到 子 式子长度
num = computeTest(ns.substring(0, post));//递归括号内的 算术运算子式
ns = ns.substring(post);//扫描位置前移
case 1://数字
if (flag) {
num = getInt(ns);//得到数字值
ns = ns.substring(getIntSize(ns));//扫描位置前移
}
if (is_type == 0) {//如果是空式子
num1 = num;
is_type = 1;
} else if (is_type == 2) {
if (fh1 == 4 || fh1 == 5) {
num1 = compute(num1, num, fh1);
is_type = 1;
} else {
num2 = num;
is_type = 3;
}
} else if (is_type == 4) {
num2 = compute(num2, num, fh2);
is_type = 3;
}
break;
case 2://+
flag2 = false;
case 3://-
ns = ns.substring(1);
if (is_type == 0) {
num1 = 0;
fh1 = flag2 ? 3 : 2;
is_type = 2;
} else if (is_type == 1) {
fh1 = flag2 ? 3 : 2;
is_type = 2;
} else if (is_type == 3) {
if (fh1 == 2 || fh1 == 3) {
num1 = compute(num1, num2, fh1);
fh1 = flag2 ? 3 : 2;
is_type = 2;
} else {
fh2 = flag2 ? 3 : 2;
is_type = 4;
}
}
break;
case 4://*
flag3 = false;
case 5:// /
ns = ns.substring(1);
if (is_type == 1) {
fh1 = flag3 ? 5 : 4;
is_type = 2;
} else if (is_type == 3) {
fh2 = flag3 ? 5 : 4;
is_type = 4;
}
break;
}
}
if (is_type == 1) {//最后剩一个数字
return num1;
}
if (is_type == 3) {//最后剩 数字 运算符号 数字
return compute(num1, num2, fh1);
}
throw new NumberFormatException();
} /**num1,num2数字,oper运算符号,返回计算结果*/
static int compute(int num1, int num2, int oper) {
switch (oper) {
case 2:
return num1 + num2;
case 3:
return num1 - num2;
case 4:
return num1 * num2;
case 5:
return num1 / num2;
}
throw new NumberFormatException();
} /**得到配对的括号的串的结束位置*/
static int getStringPost(String str) {
int post = 1;//当前位置
int count = 1;//左括号数
int pmax = str.length();//总长
while (post <= pmax) {
if (str.charAt(post) == ')') {
count--;
if (count == 0) {//如果找到配对的括号则返回
return post + 1;
}
} else if (str.charAt(post) == '(') {
count++;
}
post++;
}
return -1;
} /**得到类型*/
static int getType(String str) {
char c = str.charAt(0);
if (c <= '9' && c >= '0') {
return 1;
} else if (c == '+') {
return 2;
} else if (c == '-') {
return 3;
} else if (c == '*') {
return 4;
} else if (c == '/') {
return 5;
} else if (c == '(') {
return 6;
}
return 0;
} /**得到当前整数*/
static int getInt(String str) {
int count = 0;
for (int i = 0, im = str.length(); i < im; i++) {
if (str.charAt(i) < '0' || str.charAt(i) > '9') {
break;
}
count++;
}
return Integer.parseInt(str.substring(0, count));
} /**得到当前整数位数*/
static int getIntSize(String str) {
int count = 0;
for (int i = 0, im = str.length(); i < im; i++) {
if (str.charAt(i) < '0' || str.charAt(i) > '9') {
break;
}
count++;
}
return count;
}
}
regex = "^(.*?)((?:(?=[-+*/])-)?\\d+(?:\\.\\d+)?)([-+])(-?\\d+(?:\\.\\d+)?)(.*)";(?:(?=[-+*/])-)?这里就排除了出现同时两个运算符并且第二个为-(比如+-或*-)
(-?\\d+(?:\\.\\d+)?)而这边解决的是小数的问题
如果还有什么疑问可以直接找我 QQ 157822248