对表达式求值时分为三步:
- 将中缀表达式转换为List,方便遍历
- 将中缀表达式的List转化为后缀表达式的List
- 计算后缀表达式表示的List的值
运行结果如下
- 将中缀表达式字符串转为List,方便后面遍历
public static List<String> getInfixArrayList(String s){
//中缀字符串转为list
List<String> arrayList = new ArrayList<String>();
int i = 0;// 用于扫描字符串
String temp = "";
s = s.replaceAll(" ", "");
while(i < s.length()){
if((s.charAt(i) < 48 || s.charAt(i) > 57) && s.charAt(i) != 46) {//不是数字且不是.
arrayList.add(""+s.charAt(i++));
}else {
temp = "";
while(i < s.length() && (s.charAt(i) == 46 || (s.charAt(i) >= 48 && s.charAt(i) <= 57))) {
temp += s.charAt(i++);
}
arrayList.add(temp);
}
}
return arrayList;
}
- 将中缀表达式的List转为后缀表达式的List
public static List<String> getSuffixArrayList(List<String> infixList){
//中缀List转后缀List
List<String> s2 = new ArrayList<String>(); //中间栈s2用list替换
Stack<String> s1 = new Stack<String>(); //符号栈s1
for(String item : infixList) {
if(item.matches("\\d+.{0,1}\\d*")) {//是数字入s2
s2.add(item);
}else {
if("(".equals(item) || s1.size() == 0 || "(".equals(s1.peek())){
s1.push(item);
}else if(")".endsWith(item)) {//遇到右括号
while(s1.size() > 0 && !s1.peek().equals("(")) {
s2.add(s1.pop());
}
s1.pop();//弹出"(" 丢弃一对括号
}else {//是符号就比较优先级
while(s1.size() > 0 && priority(item) <= priority(s1.peek())) {
s2.add(s1.pop());
}
s1.push(item);
}
}
}
while(s1.size() > 0) {
s2.add(s1.pop());
}
return s2;
}
- 对后缀表达式的List求值
public static double clacu(List<String> suffixList) {
//后缀list求值
double res = 0;
Stack<String> stack = new Stack<String>();
for(String item : suffixList) {
if(item.matches("\\d+.{0,1}\\d*")) {//如果是多位数
stack.push(item);
}else {
double n1 = Double.parseDouble(stack.pop());
double n2 = Double.parseDouble(stack.pop());
if(item.equals("-")) {
res = n2 - n1;
}else if(item.equals("+")) {
res = n2 + n1;
}else if(item.equals("*")) {
res = n2 * n1;
}else if(item.equals("/")) {
res = n2 / n1;
}else {
throw new RuntimeException("找不到符号~");
}
stack.push(""+res);
}
}
return res;
}
public static int priority(String c) {
//返回符号的优先级,数字越大优先级越高
int ADD = 1;
// int SUB = 1;
int MUL = 2;
// int DIV = 2;
if("+".equals(c) || "-".equals(c)) return ADD;
else if("*".equals(c) || "/".equals(c)) return MUL;
else return 0;
}
- 测试程序
public static void main(String[] args) {
String str = "1.2 + ((2 + 3) * 4) - 5";
System.out.println("原表达式:"+str);
List<String> infixlist = getInfixArrayList(str);//将中缀表达式转为List方便遍历
System.out.println("中缀List:"+infixlist);
List<String> Suffixlist = getSuffixArrayList(infixlist);//将中缀List转为后缀List
System.out.println("后缀List:"+Suffixlist);
double result = clacu(Suffixlist);//对后缀List求值
System.out.printf("%s = %.2f\n",str,result);
}