数学表达式计算算法,为了方便直接将数值类型格式化为了double,看到的朋友帮忙测测
计算规则,先%,后* /再+ -先括号内在括号外先左后右,只是写了个算法的思路,有些细节没有处理,有时间补上。
此算法采用操作符进栈比较优先级的策略决定是否计算栈顶操作符的表达式。记得大学时写编译器的时候我用的是循环检测栈内最内层的括号,找到后按照 % * / + -的优先级顺序进行脱括号计算,知道没有括号后在进行一轮的循环计算。此算法代码的实现上和逻辑上较为简单,本文的算法是根据数据结构中给的算法思路整理的java代码算法。
/**author:a276202460*CreateDate:2009-11-17**/
package com.rich.expression;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ExpressionOptr {
private static final String optrflag = "(#+-#*/#%)";
private static final Pattern errorpattern = Pattern.compile("([^0-9//+//-//*///(//)//. %]|" + "[^0-9]{1,}//.[^0-9]{1,}|" + "^//.|" + "//.$|" + "//([^0-9//( ]|" + "[^0-9//) ]//)|" + "[^//+//-//*///(% ]//(|" + "//)[^//+//-//*///) %])");
private static Matcher m;
public static void main(String[] s) {
String expression = " 3.2 * ( 5.3+3.4-5.5 / 4 ) + 9 -4 %(5-2) ";
System.out.println(getResult(expression));
System.out.println(3.2 * (5.3 + 3.4 - 5.5 / 4) + 9 - 4 % (5 - 2));
}
public static double getResult(String expression) {
String validatestr = validateExpression(expression);
if (validatestr != null) {
throw new RuntimeException("Error with unexpected char:" + validatestr);
}
expression = expression.trim();
expression = expression.replaceAll("//+", " + ").replaceAll("//-", " - ").replaceAll("//*", " * ").replaceAll("/", " / ").replaceAll("%", " % ").replaceAll("//(", " ( ").replaceAll("//)", " ) ").replaceAll(" +", " ").replaceAll("^ ", "").replaceAll(" $", "");
Stack valuestack = new Stack();
Stack optrstack = new Stack();
String[] expchars = expression.split(" +");
int startindex = 0;
String ep;
String top;
while (startindex < expchars.length) {
ep = expchars[startindex];
startindex++;
if (optrflag.indexOf(ep) == -1) {
valuestack.push(ep);
} else {
if (optrstack.isEmpty()) {
optrstack.push(ep);
continue;
}
top = optrstack.pop().toString();
int rs = comparepri(top, ep);
if (rs == 0) {
continue;
} else if (rs < 0) {
optrstack.push(top);
optrstack.push(ep);
} else {
startindex--;
double b = Double.parseDouble(valuestack.pop().toString());
double a = Double.parseDouble(valuestack.pop().toString());
valuestack.push("" + getresult(a, b, top));
}
}
}
while (!optrstack.isEmpty()) {
double b = Double.parseDouble(valuestack.pop().toString());
double a = Double.parseDouble(valuestack.pop().toString());
valuestack.push("" + getresult(a, b, optrstack.pop().toString()));
}
return Double.parseDouble(valuestack.pop().toString());
}
public static String validateExpression(String expression) {
expression = expression.replaceAll(" +", " ");
m = errorpattern.matcher(expression);
if (m.find()) {
return m.group(1);
}
m = errorpattern.matcher(expression.trim());
if (m.find()) {
return m.group(1);
}
return null;
}
private static int comparepri(String top, String insert) {
int i = optrflag.indexOf(top);
int j = optrflag.indexOf(insert);
if (i < 0 || i == 1 || i == 4 || i == 7 || j < 0 || j == 1 || j == 4 || j == 7) {
throw new RuntimeException("Error");
}
int distance = j - i;
if (distance == -9) {
throw new RuntimeException("Error");
}
if (distance == 9) {
return 0;
} else if (i == j && i != 0) {
return 1;
} else if (i == j && i == 0) {
return -1;
} else if (j == 9) {
return 1;
} else if (j == 0) {
return -1;
} else if (j - i <= 1) {
return 1;
} else {
return -1;
}
}
public static double getresult(double a, double b, String operator) {
char operat = operator.toCharArray()[0];
switch (operat) {
case '%':
return getmod(a, b);
case '+':
return getsum(a, b);
case '-':
return getgap(a, b);
case '*':
return getproduct(a, b);
case '/':
return getquotient(a, b);
default: {
throw new RuntimeException("Error");
}
}
}
public static double getsum(double a, double b) {
return a + b;
}
public static double getgap(double a, double b) {
return a - b;
}
public static double getproduct(double a, double b) {
return a * b;
}
public static double getquotient(double a, double b) {
if (b == 0) {
throw new RuntimeException("Error with / 0");
}
return a / b;
}
public static double getmod(double a, double b) {
if (b == 0) {
throw new RuntimeException("Error with % 0");
}
return a % b;
}
}
学生时代的算法现在用到了自己的产品中,发现各方面表现还不错,特回来备注留念下当时的烂代码。