中缀表达式
中缀表示法(或 中缀记法 )是一个通用的 算术 或 逻辑公式表示方法,操作符是以中缀形式处于 操作数 的中间(例:3 + 4)。与前缀表达式 (例:+ 3 4 )或后缀表达式 (例:3 4 + )相比,中缀表达式不容易被电脑解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。
中缀表达式计算器
中缀表达式计算器基于ArrayStack实现,它将数字和操作符按照相应的规定分别入栈弹栈于各自的栈,具体实现规定如下:
- 创建两个栈 操作符栈 数字栈
- 如果遇到数字 直接进数字栈
- 如果遇到操作符
-
1.如果操作符栈为空 直接进
-
2.如果操作符栈顶为( 直接进
-
3.如果操作符栈顶为其他操作符
-
(1)当前的操作符比栈顶的操作符的优先级大 直接进
-
(2)当前的操作符比栈顶的操作符的优先级等于或小于 将操作符栈中比当前操作符优先级大的所有操作符处理
-
直到空栈 、( 、小优先级的操作符为止
-
4.当前操作符是) 将操作符栈中( 上面的所有操作符处理掉 最终(弹栈即可
代码实现如下:
public class Infixalculator {
public static void main(String[] args) {
String expression = "(10+20/2*3)/2+8";
//格式化表达
expression = insertBlanks(expression);
String[] tokens = expression.split(" ");
//数字栈
ArrayStack<Integer> numStack = new ArrayStack<>();
//操作符栈
ArrayStack<Character> operatorStack = new ArrayStack<>();
for (String token : tokens) {
//过滤空字符串
if (token.length() == 0) {
continue;
}
else if(token.charAt(0) == '+' || token.charAt(0) == '-'){
//判断是否是“+”或“-”如果是 让操作符栈中之前的所有操作符处理
while (!operatorStack.isEmpty() &&
(operatorStack.peek() == '+' ||
operatorStack.peek() == '-' ||
operatorStack.peek() == '*' ||
operatorStack.peek() == '/' )){
processAnOperator(numStack,operatorStack);
}
operatorStack.push(token.charAt(0));
}else if(token.charAt(0) == '*' || token.charAt(0) == '/'){
//判断是否是“*”或“/” 如果是 让操作符栈中之前 * / 的所有操作符处理
while (!operatorStack.isEmpty() &&
(operatorStack.peek() == '*' || operatorStack.peek() == '/')){
processAnOperator(numStack,operatorStack);
}
operatorStack.push(token.charAt(0));
}else if(token.charAt(0) == '('){
operatorStack.push('(');
}else if (token.charAt(0) == ')'){
//处理左括号(栈顶)之前的操作符
while (operatorStack.peek() != '('){
processAnOperator(numStack,operatorStack);
}
operatorStack.pop();
}else { //最后剩下数字
numStack.push(new Integer(token));
}
}
//将剩余的数字和操作符处理掉
while(!operatorStack.isEmpty()){
processAnOperator(numStack,operatorStack);
}
System.out.println(numStack.pop());
}
//在数字栈中弹出两个数字,并在操作符中弹出一个操作符 做运算
private static void processAnOperator(ArrayStack<Integer> numStack, ArrayStack<Character> operatorStack) {
char op = operatorStack.pop();
int num1 = numStack.pop();
int num2 = numStack.pop();
//num1 or num2
if (op == '+'){
numStack.push(num2 + num1);
}else if (op == '-'){
numStack.push(num2 - num1);
}else if (op == '*'){
numStack.push(num2 * num1);
}else {
numStack.push(num2 / num1);
}
}
private static String insertBlanks(String expression) {
StringBuilder sb = new StringBuilder();
//遍历表达式
char c;
for (int i = 0; i < expression.length(); i++) {
c = expression.charAt(i);
//如果是符号,则在符号前后增加空格
if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/'){
sb.append(" ");
sb.append(c);
sb.append(" ");
}else { //如果遇到数字 则原封不动添加在sb
sb.append(c);
}
}
return sb.toString();
}
}