基于Java语言的表达式计算
一个表达式包含+、—、*、/、()运算符,要计算表达式的值。此处运用栈,分别存储操作数和操作符,大体思路是利用双栈把中缀表达式转换成后缀表达式进行计算。
1.拆分数字与运算符
遇到运算符截断、存储、清空。
2.转后缀表达式
栈A存放后缀表达式,栈B存放运算符
记 B栈顶运算符为a1,当前运算符为a2(若a2为数字直接 a2->A )
1)若 a1>a2,a1->A,a2->B
1)若 a1<a2,a2->B;
2)若 a1>=a2
1.若a1>a2,a1->A;(只要该条件满足则一直执行,使得优先级高的运算符放在A中)
2.将高级运算符都排除后,要判断a1=a2 ?( 即是否为()相遇)
如果为左右括号的话就把做括号弹出,否则把a2->B。可以一直排除比它高级的运算法,但是只能抵消一个左括号
PS: a1>a2 表示 在此式中先算a1再算a2,a1与a2的关系在初始化中建立。
3.计算后缀表达式
从左往右扫描,遇到运算符则处理前两位数字
首先,将给定的字符串转为中缀表达式;使用List<String>保存表达式:程序代码如下
/**
* 将字符串转化为List
*
* @param str
* @return
*/
public ArrayList<String> getStringList(String str) {
ArrayList<String> result = new ArrayList<String>();
String num = "";
for (int i = 0; i < str.length(); i++) {
if (Character.isDigit(str.charAt(i)) || str.charAt(i) == ‘.‘) {
num = num + str.charAt(i);
} else {
if (num != "") {
result.add(num);
}
result.add(str.charAt(i) + "");
num = "";
}
}
if (num != "") {
result.add(num);
}
return result;
}
然后,将中缀表达式转变为后缀表达式,程序代码如下:
/**
* 将中缀表达式转化为后缀表达式
*
* @param inOrderList
* @return
*/
public ArrayList<String> getPostOrder(ArrayList<String> inOrderList) {
ArrayList<String> result = new ArrayList<String>();
Stack<String> stack = new Stack<String>();
stack.push("#");
for (int i = 0; i < inOrderList.size(); i++) {
if (Character.isDigit(inOrderList.get(i).charAt(0))) {
result.add(inOrderList.get(i));
} else {
switch (inOrderList.get(i).charAt(0)) {
case ‘(‘:
stack.push(inOrderList.get(i));
break;
case ‘)‘:
while (!stack.empty() && !stack.peek().equals("(")) {
result.add(stack.pop());
}
if (!stack.empty()) {
stack.pop();
}
break;
default:
while (!stack.empty() && !("#".equals(stack.peek()))
&& compare(stack.peek(), inOrderList.get(i))) {
result.add(stack.pop());
}
stack.push(inOrderList.get(i));
break;
}
}
}
while (!stack.empty() && !("#".equals(stack.peek()))) {
result.add(stack.pop());
}
return result;
}
其次,还得比较运算符的优先级,程序代码如下所示:
/**
* 比较运算符等级
*
* @param peek
* @param cur
* @return
*/
public static boolean compare(String peek, String cur) {
if ("*".equals(peek)
&& ("/".equals(cur) || "*".equals(cur) || "-".equals(cur) || "+"
.equals(cur))) {
return true;
} else if ("/".equals(peek)
&& ("/".equals(cur) || "*".equals(cur) || "-".equals(cur) || "+"
.equals(cur))) {
return true;
} else if ("+".equals(peek) && ("+".equals(cur) || "-".equals(cur))) {
return true;
} else if ("-".equals(peek) && ("+".equals(cur) || "-".equals(cur))) {
return true;
} else if ("#".equals(peek)) {
return true;
}
return false;
}
最后,计算表达式的值,程序代码如下:
/**
* 计算后缀表达式
*
* @param postOrder
* @return
*/
public Float calculate(ArrayList<String> postOrder) {
Stack<Float> stack = new Stack<Float>();
for (int i = 0; i < postOrder.size(); i++) {
if (Character.isDigit(postOrder.get(i).charAt(0))) {
stack.push(Float.valueOf(postOrder.get(i)));
} else {
Float back = (Float) stack.pop();
Float front = (Float) stack.pop();
float result = 0F;
switch (postOrder.get(i).charAt(0)) {
case ‘+‘:
result = front + back;
break;
case ‘-‘:
result = front - back;
break;
case ‘*‘:
result = front * back;
break;
case ‘/‘:
result = front / back;
break;
}
stack.push(result);
}
}
return stack.pop();
}
定义一个测试类,测试代码
public static void main(String[] args) {
EvaluateExpress exp = new EvaluateExpress();
String str = "24+(89-23*6)/3";
ArrayList<String> result = exp.getStringList(str);
System.out.print("中缀表达式:");
for (String s : result) {
System.out.print(s);
}
System.out.println("\n------------------");
ArrayList<String> postResult = exp.getPostOrder(result);
System.out.print("后缀表达式:");
for (String strs : postResult) {
System.out.print(strs);
}
System.out.println("\n-------------");
float calResult = exp.calculate(postResult);
System.out.println("计算结果为:" + calResult);
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。