用栈完成计算一个表达式

用栈完成计算一个表达式

思路:

  1. 遍历我们的表达式
  2. 如果发现是数字,入栈
  3. 如果是一个运算符,分情况讨论:
    3.1 如果发现当前的符号栈为空,直接入栈
    3.2 如果符号栈有操作符,就先进行比较,
    如果当前操作符的优先级小于或者等于栈中的操作符,
    从数栈中pop出两个数,再从符号栈中pop出一个符号,进行计算,然后将当前的操作符入栈,如果当前的操作符的优先级大于栈中的操作符,就直接入符号栈
  4. 当表达式扫描完毕,就顺序从数栈和符号栈中pop出相应的数和符号,并运行。
  5. 最后在数栈只有一个数字,就是表达式的结果。

仅支持整数运算

package com.psyche.calculator;

import java.util.Stack;

public class StackCalculatorDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		StackCalculator calc = new StackCalculator();
		String str = "1+2*3-6/2";
		System.out.printf("%s = %d", str, calc.calc(str));
	}

}

class StackCalculator {
	private Stack<Integer> numStack;
	private Stack<Character> operStack;
	private char[] exp;

	// 操作符的优先级 (* /) > (+ -)
	public int calc(String expression) {
		exp = new char[expression.length()]; // 字符数组 存放表达式
		exp = expression.toCharArray();
		numStack = new Stack<Integer>(); // 数字栈
		operStack = new Stack<Character>(); // 操作符栈

		// 遍历字符数组
		for (int i = 0; i < exp.length; i++) {
			// 判断该字符是数字还是操作符
			if (exp[i] >= '0' && exp[i] <= '9') { // 数字
				numStack.push(Integer.valueOf(exp[i] - 48));
			} else if (exp[i] == '+' || exp[i] == '-' || exp[i] == '*' || exp[i] == '/') { // 运算符
				char val = exp[i];
				switch (val) {
				// 符号:
				// +----------------------------------------------------------------------------------------------------------------
				case '+':

					// 1.判断符号栈是否为空,空直接入符号栈
					if (operStack.isEmpty()) {
						operStack.push(val);
					} else {

						pushAndCalc(operStack.pop());
						operStack.push(val);

					}
					break;

				// 符号: -
				// -----------------------------------------------------------------------------------
				case '-':
					// 1.判断符号栈是否为空,空直接入符号栈
					if (operStack.isEmpty()) {
						operStack.push(val);
					} else {
						pushAndCalc(operStack.pop());
						// 符号压栈
						operStack.push(val);
					}
					break;

				// 符号: *
				// -------------------------------------------------------------------------------------------
				case '*':

					// 1.判断符号栈是否为空,空直接入符号栈
					if (operStack.isEmpty()) {
						operStack.push(val);
					} else {
						// 判断
						if (operStack.peek() == '+' || operStack.peek() == '-') {
							operStack.push('*');
						} else {
							pushAndCalc(operStack.pop());
							// 符号压栈
							operStack.push(val);
						}

					}

					break;

				// 符号: /
				// --------------------------------------------------------------------------------------------------
				case '/':

					// 1.判断符号栈是否为空,空直接入符号栈
					if (operStack.isEmpty()) {
						operStack.push(val);
					} else {
						// 判断
						if (operStack.peek() == '+' || operStack.peek() == '-') {
							operStack.push('/');
						} else {
							pushAndCalc(operStack.pop());
							// 符号压栈
							operStack.push(val);
						}

					}

					break;

				default:
					break;
				}
			} else {
				throw new RuntimeException("表达式存在非法字符"); // 非法字符
			}

		}
		// 遍历之后若符号栈不为空,弹出所有符号
		while (!operStack.isEmpty()) {
			pushAndCalc(operStack.pop());
		}
		return numStack.pop();
	}

	public void pushAndCalc(char oper) { // 根据运算符进行运算,自动从数据栈中去数据。
		int val1 = numStack.pop();
		int val2 = numStack.pop();
		switch (oper) {
		case '+':
			numStack.push(val2 + val1);
			break;

		case '-':
			numStack.push(val2 - val1);
			break;

		case '*':
			numStack.push(val2 * val1);
			break;

		case '/':
			numStack.push(val2 / val1);
			break;
		}
	}

}

运行结果
整数计算器运行结果

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值