中缀表达式是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:10+5,与前缀表达式(例:* 5 10),或后缀表达式(例:5 10 -)相比,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。
与前缀或后缀记法不同的是,中缀记法中括号是必需的。
我们以" (10+20/2*3)/2+8 "这个中缀表达式为例来实现中缀计算器:
public class InfixCalculator {
public static void main(String[] args) {
String express = "(10+20/2*3)/2+8";
int result = evaluateExpression(express);
System.out.println(result);
}
//计算中缀表达式
private static int evaluateExpression(String express) {
express = insertBlanks(express); //按指定格式格式化字符串
String[] tokens = express.split(" "); //将字符串以“ ”进行分割
ArrayStack<Character> operatorStack = new ArrayStack<Character>(); //创建只存放运算符的栈
ArrayStack<Integer> numberStack = new ArrayStack<Integer>(); //创建只存放数字的栈
for (String token : tokens){
if(token.length() == 0){ //过滤空串 如:“”
continue;
}else if(token.equals("+") || token.equals("-")){ //如果遍历到 + - 号
while (!operatorStack.isEmpty() && (operatorStack.peek() == '+' ||
operatorStack.peek() == '-' ||
operatorStack.peek() == '*' ||
operatorStack.peek() == '/')){ //如果之前是别的+ - * / 则需要弹栈 并计算
processAnOperator(operatorStack, numberStack);
}
operatorStack.push(token.charAt(0)); //如果操作符栈为空 或者 不为空但栈顶为( 就将字符压入栈中
}else if(token.equals("*") || token.equals("/")){ //如果遍历到 * / 号
while (!operatorStack.isEmpty() && (operatorStack.peek() == '*' || operatorStack.peek() == '/')){ //如果之前是别的* / 则需要弹栈 并计算
processAnOperator(operatorStack, numberStack);
}
operatorStack.push(token.charAt(0)); //如果操作符栈为空 或者 不为空但栈顶为( 就将字符压入栈中
}else if (token.equals(")")){//如果遍历到 )
while (operatorStack.peek() != '('){ //只要操作符栈的栈顶不是左括号( 就挨个弹栈计算即可
processAnOperator(operatorStack, numberStack);
}
operatorStack.pop(); //最后 清掉左括号
}else if (token.equals("(")){ //如果遍历到 (
operatorStack.push(token.charAt(0)); //就直接将字符压栈
}else{
numberStack.push(Integer.parseInt(token)); //如果遍历到数字 就直接将数组压入数字栈
}
}
while (!operatorStack.isEmpty()){ //处理最后面的操作符
processAnOperator(operatorStack, numberStack);
}
return numberStack.pop(); //最后的结果就是数字栈最后的栈顶元素
}
//操作符栈弹栈一个元素 数字栈弹栈两个数字 进行计算 并将新的结果进栈到数字栈
private static void processAnOperator(ArrayStack<Character> operatorStack, ArrayStack<Integer> numberStack) {
char operator = operatorStack.pop(); //弹出字符栈中的一个字符
int num1 = numberStack.pop(); //弹出数字栈中的第一个数组
int num2 = numberStack.pop(); //弹出数字栈中的第二个数组
//先弹出的数字应放在运算符右边运算 后弹出的数字应放在运算符左边运算
//num2 operator num1
if(operator == '+'){
numberStack.push(num2 + num1 );
}else if (operator == '-'){
numberStack.push(num2 - num1);
}else if(operator == '*'){
numberStack.push(num2 * num1);
}else{
numberStack.push(num2 / num1);
}
}
//对原表达式进行格式化处理 给所有的非数字字符两边添加空格
//是表达式变为“ ( 10 + 20 / 2 * 3 ) / 2 + 8”
private static String insertBlanks(String express) {
StringBuilder newExpe = new StringBuilder();
for(int i = 0; i < express.length(); i++){
char c = express.charAt(i);
if(c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/'){
newExpe.append(' ');
newExpe.append(c);
newExpe.append(' ');
}else{
newExpe.append(c);
}
}
return newExpe.toString();
}
}
该表达式的运行结果为:

本文探讨了中缀表达式在计算中的应用,解释了中缀表达式不易于计算机直接解析但符合人类习惯的特点。通过举例‘(10+20/2*3)/2+8’,阐述了如何使用动态数组栈来实现中缀表达式的计算过程。
4436

被折叠的 条评论
为什么被折叠?



