Reverse Polish Notation simple calculator function

Overview of issues

We completed a reverse Polish calculator, required to complete the following tasks

  1. Enter an infix expression, converted into postfix expression (reverse Polish notation), using the calculation result stack
  2. Required to support parentheses, and a number of integers, we do not consider the issue fractional

Reverse Polish Notation writing

Reverse Polish Notation (Reverse Polish notation, RPN, or reverse Polish notation), also called postfix expression, operators of the value written on the back

Why do you want to use Reverse Polish Notation

Achieve reverse Polish notation is not really difficult, but why should the seemingly simple infix expressions into postfix notation turn it?
In fact, just the infix expression is simple for humans, but for the computer, infix expression is a very complex structure. The postfix expression is easy to understand the structure of the computer is a. Because the calculation is performed i.e. a stack structure sequentially advanced out after performing

Turn postfix expression step
  1. First prepare two stacks S1, S2, respectively, for storing symbols and store values ​​from the left-most decorated expressions start value.
  2. When an operand is fetched, the values ​​directly into the stack S2.
  3. When an operator is removed, if the stack is empty directly into the stack Sl operator, the operator if the current level (not including the bracket operator) is larger than the stack operators, but also directly into the symbol stack Sl; when the operator is less than the current top of the stack operator, pop the stack symbols into the symbol S2 until the current value of the stack is greater than the operator-level stack operator, the operator pressed the current operator stack when the stack is (current parentheses operators directly into the stack symbol S1.
  4. When the operator is removed (in brackets, the operator directly into the stack
  5. When taken out of the operator) bracket, the pop-up operator stack symbol (finally (popped up.
  6. Before the operation is repeated until the complete traversal formula
  7. Finally, reverse printing our value stack S2 can get our reverse Polish notation.
for example

The 1 + ((2 + 3) * 4) - 5 postfix expression is converted to 1 2 3 * 4 + 5 - +

Operands fetched S1 stack (the stack bottom -> stack) S2 stack (the stack bottom -> stack) Step Description
1 air 1 The numerical value 1 is pressed into the stack
+ + 1 Symbol stack is empty, stack directly into the symbol
+ ( 1 Operator of (directly into the symbol stack
+ ( ( 1 Operator of (directly into the symbol stack
2 + ( ( 1 2 Operand value is taken directly into the value of the stack
+ + ( ( + 1 2 The top of the stack as the stack symbol (symbols in parentheses pressure directly into the stack
3 + ( ( + 1 2 3 Operand value is taken directly into the value of the stack
+ ( 1 2 3 + Remove the operator to) a symbol pop pop the stack until the nearest symbol (and the pop value symbol is pressed into the stack
* + ( * 1 2 3 + * Remove the operator to operator and the current level is greater than the operator-level stack, the stack directly into the symbol
4 + ( * 1 2 3 + 4 Operand value is taken directly into the value of the stack
+ 1 2 3 + 4 * Remove the operator to) a symbol pop pop the stack until the nearest symbol (and the pop value symbol is pressed into the stack
- + - 1 2 3 + 4 * * Remove the operator to operator and the current level is greater than the operator-level stack, the stack directly into the symbol
5 + - 1 2 3 + 4 * 5 Operand value is taken directly into the value of the stack
air air 1 2 3 + 4 * 5 - + Empty symbols stack S1

Reverse Polish Notation calculations

  1. Create a stack S1 is used to store value, from left to right traverse Reverse Polish Notation (postfix notation)
  2. Remove the number of values ​​onto the stack
  3. The number of symbols is taken out, the stack pop two values ​​is calculated, and the calculated values ​​result onto the stack.
  4. Repeat until the bottom portion 3 postfix
Values ​​removed Stack (bottom of the stack -> stack) Step Description
1 1 Operand value onto the stack
2 1 2 Operand value onto the stack
3 1 2 3 Operand value onto the stack
+ 1 5 Operand symbols, two values ​​for the pop-up operation, and the operation result onto the stack
4 1 5 4 Operand value onto the stack
* 1 20 Operand symbols, two values ​​for the pop-up operation, and the operation result onto the stack
5 1 20 5 Operand value onto the stack
- 1 15 Operand symbols, two values ​​for the pop-up operation, and the operation result onto the stack
+ 16 Operand symbols, two values ​​for the pop-up operation, and the operation result onto the stack

Code implements a simple calculator function

import java.util.List;
import java.util.ArrayList;

public class Calculator {
	public static void main(String[] args) {
		String express = "1+((2+3)*4)-5":
		List<String> suffixExpression = SuffixExpression.toSuffixExpression(list);
        int calculate = SuffixExpression.calculate(suffixExpression);
        System.out.println(calculate);
	}
	
	/**
	* 将一个算式解析成一个个元素
	* @param 需要截取的字符串
	*/
	public static List<String> strToList(String str) {
		if (str == null || str.length() <= 0) {
			throw new IllegalArgumentException();
		}
		List<String> list = new ArrayList<String>();
		for (int i = 0;i < str.length();i++) {
			if (str.charAt() < 48 || str.charAt(i) > 57) {
				list.add("" + str.charAt(i));
			} else {
				String sub = "":
				while (i < str.length() && str.charAt(i) >= 48 && str.charAt(i) <= 57) {
					sub += str.charAt(i);
					list.add(sub);
					i++;
				}
			}
		}
		return list;
	}
	
	/**
	* 将中缀表达式转逆波兰表达式(后缀表达式)
	* @param 需要转的中缀表达式
	*/
	public static List<String> toSuffixExpression(List<String> list) {
		if (list == null || list.isEmpty()) {
			throw new IllegalArgumentException();
		}
		// 用于存放操作符的
		Stack<String> stack = new Stack<String>();
		
		// 用于存放数值,由于最后我们是需要逆序输出数值栈,所以这里直接用集合替代栈,可以免去逆序打印
		List<String> suffix = new ArrayList<String>();
		for (String str:list) {
			if (str.matches("\\d")) {
				suffix.add(str);
			} else if (str.equals("(")) {
				stack.push(str);
			} else if (str.equals(")")) {
				while (!stack.peek().equals("(")) {
					suffix.add(stack.pop());
				}
				stack.pop();
			} else {
				while (stack.size() > 0 && getValue(str) < getValue(stack.peek())) {
					suffix.add(stack.pop());
				}
				stack.push(str);
			}
		}
		while (stack.size() > 0){
            suffix.add(stack.pop());
        }
	}
	
	/**
	* 根据逆波兰表达式计算结果
	* @param 需要计算的逆波兰表达式
	*/
	public static int calculator(List<String> list) {
		if (list == null || list.isEmpty()) {
			throw new IllegalArgumentException();
		}
		Stack<String> stack = new Stack<String>();
		for (String str:list) {
			if (str.matches("\\d")) {
				stack.push(str);
			} else {
				int num1 = Integer.parseInt(stack.pop());
				int num2 = Integer.parseInt(stack.pop());
				if (str.equals("+")){
                    stack.push(String.valueOf(num1+num2));
                }else if (str.equals("-")){
                    stack.push(String.valueOf(num2-num1));
                }else if (str.equals("*")){
                    stack.push(String.valueOf(num1*num2));
                }else if (str.equals("/")){
                    stack.push(String.valueOf(num2/num1));
                }
			}
		}
		return Integer.parseInt(stack.pop());
	}
	
	/**
	* 计算输入字符的优先级
	* @param 需要判断的字符
	*/
	public static int getValue(String str){
        int result;
        switch (str){
            case "+":
                result =  1;
                break;
            case "-":
                result =  1;
                break;
            case "*":
                result =  2;
                break;
            case "/":
                result =  2;
                break;
            default:
               result = 0;
               break;
        }
        return result;
    }
}

Code is finished, the younger only a limited capacity, it is inevitable loopholes, pointing Comments welcome of all the great God! ! !

Released seven original articles · won praise 3 · Views 270

Guess you like

Origin blog.csdn.net/justLym/article/details/104550194