Java实现表达式计算

问题描述

输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。

输入格式

输入一行,包含一个表达式。

输出格式

输出这个表达式的值。

样例输入

1-2+3*(4-5)

样例输出

-4

数据规模和约定

表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

思路

简单中缀表达式计算:

  •  创建一个运算符栈和操作数栈
    
  •  从左到右扫描表达式:
    
  •     扫描到数字直接入操作数栈
    
  •     扫描到运算符:
    
  •         如果比运算符栈顶的符号优先级高,则直接入栈
    
  •         如果比运算符栈顶的符号优先级低,则弹出栈顶符号和操作数栈中的两个数进行运算,结果再入栈
    
  •     扫描到左括号直接入栈
    
  •     扫描到右括号则循环弹出栈顶符号和操作数栈中的两个数进行运算,结果入栈,直到栈顶符号为左括号为止
    
  •  如果表达式扫描完毕运算符栈还有元素,则继续出栈计算直到运算符栈为空
    
  •  最后操作数栈的栈顶元素即为表达式的运算结果
    

代码

import java.util.Scanner;
import java.util.Stack;
public class Calculate {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		String expression = input.nextLine();
		input.close();
		System.out.println(stack(expression));
	}
	public static Integer stack(String expression) {
		Stack<Integer> operand = new Stack<>(); //操作数栈
		Stack<String> operator = new Stack<>();//操作符栈
		StringBuilder exp = new StringBuilder(expression);//将表达式保存为可变字符串
		for (int i = 0; i < exp.length(); i++) {
			if(exp.charAt(i) == '+' || exp.charAt(i) == '-' || 
					exp.charAt(i) == '*' || exp.charAt(i) == '/') {  
				if(operator.empty()) {
					operator.push(String.valueOf(exp.charAt(i)));
				}
				else if(priority(String.valueOf(exp.charAt(i))) > priority(operator.peek())) {
					operator.push(String.valueOf(exp.charAt(i)));
				}
				else {//运算符优先级低,弹出栈顶元素进行运算
					Integer obj1 = operand.pop();
					Integer obj2 = operand.pop();
					Integer res = result(obj2, obj1, operator.pop());
					operand.push(res);
					operator.push(String.valueOf(exp.charAt(i)));
				}
			}
			else if(exp.charAt(i) == '(') {
				operator.push(String.valueOf(exp.charAt(i)));
			}
			else if(expression.charAt(i) == ')') {//扫描到右括号则循环弹出栈顶符号和操作数栈中的两个数进行运算,结果入栈,知道栈顶符号为左括号为止
				while(!operator.peek().equals("(")) {
					Integer obj1 = operand.pop();
					Integer obj2 = operand.pop();
					Integer res = result(obj2, obj1, operator.pop());
					operand.push(res);
				}
				operator.pop();
			}
			else if(exp.charAt(i) >= '0' && exp.charAt(i) <= '9'){   //扫描到数字直接入操作数栈
				int j = i + 1;
				StringBuilder num = new StringBuilder(String.valueOf(exp.charAt(i))); //处理多位数的情况
				while(exp.charAt(j) >= '0' && exp.charAt(j) <= '9') {
					num.append(exp.charAt(j));
					exp.setCharAt(j, ' ');//将拼接过的数字置为空,以免重复入栈
					j++;
					
				}
				operand.push(Integer.valueOf(num.toString()));
				
			}
			else {
				continue;
			}
		}
		if(!operator.empty()) {  //表达式扫描完运算符栈还未空继续计算
			while(!operator.empty()) {
				Integer obj1 = operand.pop();
				Integer obj2 = operand.pop();
				Integer res = result(obj2, obj1, operator.pop());
				operand.push(res);
			}
		}
		return operand.peek();
	}
	public static int priority(String operator) {   //运算符的优先级,数字越大,优先级越大
		if(operator.equals("+") || operator.equals("-"))
			return 1;
		else if(operator.equals("*") || operator.equals("/"))
			return 2;
		else
			return 0;
	}
	public static Integer result(int obj1, int obj2, String operator) {
		Integer res = 0;
		switch(operator) {
		case "+": res = obj1 + obj2;break;
		case "-": res = obj1 - obj2;break;
		case "*": res = obj1 * obj2;break;
		case "/": res = obj1 / obj2;
		}
		return res;
	}
}

发布了33 篇原创文章 · 获赞 3 · 访问量 3784

猜你喜欢

转载自blog.csdn.net/qq_43169220/article/details/103618067