您的位置:首页 > 编程语言 > Java开发

Java —— 表达式计算器

2016-04-09 19:24 393 查看

Java —— 表达式计算器

在JavaScript中,我们知道有eval()这个函数,专门用来运行表达式字符串,用起来非常方便。但是在C++、Java中,就没有这么方便的工具给我们使用了。
对一个表达式求值的步骤有两步:
① 中缀表达式求前缀表达式
② 前缀表达式运算求值
这两个步骤分别利用两个栈,操作符栈与操作数栈;
具体的讲解请参考《MFC 实现 加减乘除,括号,乘方的 计算器
程序源代码:
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
import java.util.Stack;

public class Work5 {
// 操作数栈
private static Stack<Double> Operands;
// 操作符栈
private static Stack<Character> Operators;
// 操作符集合
private static final Set<Character> C_OperatorSet = new HashSet<Character>() {
/**
*
*/
private static final long serialVersionUID = 1L;

{
add('+');
add('-');
add('*');
add('/');
add('^');
add('(');
add(')');
}
};

private static int getOperatorPriority(char ch) {
if (ch == '+' || ch == '-')
return 0;
else if (ch == '*' || ch == '/')
return 1;
else if (ch == '^')
return 3;
else
return -1;
}

private static String infixToSuffix(String expression) {
Operators = new Stack<>();
Operators.clear();
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < expression.length(); i++) {
char ch = expression.charAt(i);
if (ch == ' ')
continue;
if (C_OperatorSet.contains(ch)) {
if (Operators.empty()) {
if (ch == ')') {
System.out.println("括号不匹配");
return sBuilder.toString();
}
Operators.push(ch);
} else if (ch == '(') {
Operators.push(ch);
} else if (ch == ')') {
char top;
while ((top = Operators.peek()) != '(') {
if (Operators.empty()) {
System.out.println("括号不匹配");
return sBuilder.toString();
}
sBuilder.append(top);
Operators.pop();
}
Operators.pop();
} else {
char top = Operators.peek();
if (getOperatorPriority(ch) <= getOperatorPriority(top)) {
while (!Operators.empty()
&& getOperatorPriority(ch) <= getOperatorPriority(top = Operators.peek())) {
sBuilder.append(top);
Operators.pop();
}
}
Operators.push(ch);
}
} else {
sBuilder.append("[" + ch);
while (i + 1 < expression.length()
&& (((ch = expression.charAt(i + 1)) == '.') || (ch >= '0' && ch <= '9'))) {
sBuilder.append(ch);
++i;
}
sBuilder.append(']');
}
}
while (!Operators.empty()) {
sBuilder.append(Operators.peek());
Operators.pop();
}
return sBuilder.toString();
}

public static double evalExp(String expression) {
Operands = new Stack<>();
Operands.clear();
double ret = 0;
String suffix = infixToSuffix(expression);
System.out.println("suffix: " + suffix);
for (int i = 0; i < suffix.length(); i++) {
if (suffix.charAt(i) == '[') {
i++;
int beginIndex = i, endIndex = i;
while (']' != suffix.charAt(i)) {
i++;
endIndex++;
}
Operands.push(Double.valueOf(suffix.substring(beginIndex, endIndex)));
} else {
double left, right, res = 0;
right = Operands.peek();
Operands.pop();
left = Operands.peek();
Operands.pop();
switch (suffix.charAt(i)) {
case '+':
res = left + right;
break;
case '-':
res = left - right;
break;
case '*':
res = left * right;
break;
case '/':
res = left / right;
break;
case '^':
res = Math.pow(left, right);
break;
}
Operands.push(res);
}
}
ret = Operands.peek();
Operands.pop();
return ret;
}

public static void main(String[] args) {
// TODO Auto-generated method stub

Scanner input = new Scanner(System.in);
System.out.println("请输入一个含+-*/^()的表达式,请确认输入合法");
String expression = input.nextLine();
System.out.println(expression + " =" + evalExp(expression));
input.close();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: