-
中缀转后缀
1.初始化:添加运算符栈opStack和存储中键结果的线性表suffixList
2.从左至右遍历中缀表达式的元素
3.遇到数字时,将其压入suffixList
4.遇到运算符时,比较其与opStack栈顶运算符的优先级
如果opStack为空,或栈顶运算符为左括号,则直接将此运算符入栈;如果优先级比栈顶运算符的高,也将运算符压入opStack;否则,将opStack栈顶的运算符弹出并压入到suffixList中,再次返回并与opStack中新的栈顶运算符相比较
5.遇到括号时:
(1)如果是左括号,则直接入栈
(2)如果是右括号,则依次弹出opStack栈顶的运算符,并压入suffixList,直到遇到左括号为止,此时将这一对括号丢弃
6.重复步骤2-5 直到表达式的最右边
7.将opStack剩余的运算符依次弹出并压入suffixList
8.依次弹出suffixList中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式 -
代码实现
public static void main(String[] args) {
String expression = "(10+20/2*3)/2+8";
expression = infixToSuffix(expression);
System.out.println(expression);
}
static String infixToSuffix(String expression) {
//操作符的栈
ArrayStack<String> opStack = new ArrayStack<>();
//后缀表达式的线性表
ArrayList<String> suffixList = new ArrayList<>();
//格式化表达式
expression = insertBlanks(expression);
String[] tokens = expression.split(" ");
for (String token : tokens) {
//过滤空串
if (token.length() == 0) {
continue;
}
//判断操作符+ - * /
if (isOperator(token)) {
/*
什么时候操作符进栈?
1.如果栈为空
2.如果栈顶是 (
3.如果栈顶是操作符,且优先级比当前token小
什么时候需要将栈顶操作符出栈?
1.栈顶操作符的优先级 >= 当前token
*/
while (true) {
if (opStack.isEmpty() || opStack.peek().equals("(") || priority(opStack.peek()) < priority(token)) {
opStack.push(token);
break;
}
suffixList.add(opStack.pop());
}
} else if (token.equals("(")) {
opStack.push(token);
} else if (token.equals(")")) {
while (!opStack.peek().equals("(")) {
suffixList.add(opStack.pop());
}
opStack.pop();
} else if (isNumber(token)) {
suffixList.add(token);
} else {
throw new IllegalArgumentException("wrong char :" + expression);
}
}
while (!opStack.isEmpty()) {
suffixList.add(opStack.pop());
}
//将数字元素和操作符元素进行拼接
StringBuilder sb = new StringBuilder();
for (int i = 0; i < suffixList.size(); i++) {
sb.append(suffixList.get(i));
sb.append(' ');
}
return sb.toString();
}
private static int priority(String token) {
if (token.equals("+") || token.equals("-")) {
return 0;
}
if (token.equals("*") || token.equals("/")) {
return 1;
}
return -1;
}
private static boolean isNumber(String token) {
return token.matches("\\d+");
}
private static boolean isOperator(String token) {
return token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/");
}
//对原表达式进行格式化处理 给所有的非数字字符两边添加空格
private static String insertBlanks(String expression) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
sb.append(' ');
sb.append(c);
sb.append(' ');
} else {
sb.append(c);
}
}
return sb.toString();
}
}
//输出结果
10 20 2 / 3 * + 2 / 8 +
- 后缀表达式计算代码实现
public static void main(String[] args) {
String expression = "(10+20/2*3)/2+8";
int result=evaluateExpression(expression);
System.out.println(expression+"="+result);
}
private static int evaluateExpression(String expression) {
ArrayStack<Character> operatorStack=new ArrayStack<>();
ArrayStack<Integer> numberStack=new ArrayStack<>();
expression=insertBlanks(expression);
String[] tokens=expression.split(" ");
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(numberStack,operatorStack);
}
operatorStack.push(token.charAt(0));
}else if (token.equals("*")||token.equals("/")){
while (!operatorStack.isEmpty()&&(operatorStack.peek()=='*'||operatorStack.peek()=='/')){
processAnOperator(numberStack,operatorStack);
}
operatorStack.push(token.charAt(0));
}else if (token.equals("(")){
operatorStack.push(token.charAt(0));
}else if (token.equals(")")){
while (operatorStack.peek()!='('){
processAnOperator(numberStack,operatorStack);
}
operatorStack.pop();
}else {
numberStack.push(new Integer(token));
}
}
while (!operatorStack.isEmpty()){
processAnOperator(numberStack,operatorStack);
}
return numberStack.pop();
}
private static void processAnOperator(ArrayStack<Integer> numberStack, ArrayStack<Character> operatorStack) {
char op=operatorStack.pop();
int num1=numberStack.pop();
int num2=numberStack.pop();
if (op=='+'){
numberStack.push(num2+num1);
}else if (op=='-'){
numberStack.push(num2-num1);
}else if (op=='*'){
numberStack.push(num2*num1);
}else {
numberStack.push(num2/num1);
}
}
private static String insertBlanks(String expression) {
StringBuilder sb=new StringBuilder();
for (int i=0;i<expression.length();i++){
char c=expression.charAt(i);
if (c == '('||c==')'||c=='+'||c=='-'||c=='*'||c=='/'){
sb.append(' ');
sb.append(c);
sb.append(' ');
}else{
sb.append(c);
}
}
return sb.toString();
}
}
//输出结果
(10+20/2*3)/2+8=28