面试经-栈实现综合计算器

思路

/*
* 先将字符串分割为一个个字符
* 接着进行判断:
* 运算符栈如果为空,则进行压栈操作
* 不为空,
* 判断是否为运算符
* 判断遍历到的运算符是否大于栈顶的元素,
* 如果大于则,继续压栈
* 反之,则从数字栈中弹出两个数字,运算符栈弹出一个字符(进行运算操作)
* 并将结果压入数字栈,将之前的运算符继续压入字符栈
* 不是运算符
* 判断是否为最后一个字符,继续压栈
* 不是最后一个字符。则要判断下一个字符是否仍然为数字,为了防止22 此类的数字被截断
* 通过 keepNum 辅助存储
* 如果为空则 压入运算符栈中
*
* 最终等所有的字符全部遍历完毕,则进行计算
*
* while(true)
* 判断循环计算
* 弹出,两个数字,一个运算符进行结果运算
* 将结果压栈
*
* 最终数字栈的栈顶即为结果
*
*/

代码实现

package Com.JW.stack;

import java.util.Scanner;

public class Calculator {

	public static void main(String[] args) {
		ArrayStacklist1 numStack = new ArrayStacklist1(10);
		ArrayStacklist1 arrStack = new ArrayStacklist1(10);

		int res = 0;
		int num1 = 0;
		int num2 = 0;
		int index = 0;
		int oper = 0;
		String keepNum = "";
		char ch;
//		String expression = "1+2*5";
		Scanner scanner = new Scanner(System.in);
		String expression = scanner.next();

		/*
		 * 先将字符串分割为一个个字符
		 * 接着进行判断:
		 *   运算符栈如果为空,则进行压栈操作
		 *   不为空,
		 *      判断是否为运算符
		 *   		判断遍历到的运算符是否大于栈顶的元素,
		 *   			如果大于则,继续压栈
		 *   			反之,则从数字栈中弹出两个数字,运算符栈弹出一个字符(进行运算操作)
		 *    			并将结果压入数字栈,将之前的运算符继续压入字符栈
		 *      	不是运算符	
		 *      		判断是否为最后一个字符,继续压栈
		 *      		不是最后一个字符。则要判断下一个字符是否仍然为数字,为了防止22 此类的数字被截断
		 *      		通过 keepNum 辅助存储
		 *    如果为空则 压入运算符栈中
		 *    
		 *    最终等所有的字符全部遍历完毕,则进行计算
		 *    	
		 *    while(true)
		 *     判断循环计算
		 *     弹出,两个数字,一个运算符进行结果运算
		 *     将结果压栈
		 *     
		 *     最终数字栈的栈顶即为结果
		 * 
		 */
		while (true) {

			ch = expression.substring(index, index + 1).charAt(0);
			if (arrStack.isOper(ch)) {
				if (!arrStack.isEmpty()) {

					if (arrStack.priority(ch) <= arrStack.priority(arrStack.peek())) {

						num1 = numStack.pop();
						num2 = numStack.pop();
						oper = arrStack.pop();
						res = arrStack.cal(num1, num2, oper);
						numStack.push(res);

						arrStack.push(ch);

					}else {
						arrStack.push(ch);
					}
				} else {
					arrStack.push(ch);
				}

			} else {

				
				//分析思路
				//1. 当处理多位数时,不能发现是一个数就立即入栈,因为他可能是多位数
				//2. 在处理数,需要向expression的表达式的index 后再看一位,如果是数就进行扫描,如果是符号才入栈
				//3. 因此我们需要定义一个变量 字符串,用于拼接
				
				keepNum += ch;
				if (index == expression.length() - 1) {
					numStack.push(Integer.parseInt(keepNum));
				} else {

					if (numStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
						numStack.push(Integer.parseInt(keepNum));
						keepNum = "";
					}

				}

			}

			index++;
			if (index >= expression.length()) {
				break;
			}
		}

		while (true) {
			if (arrStack.isEmpty()) {
				break;

			}

			num1 = numStack.pop();
			num2 = numStack.pop();
			oper = arrStack.pop();
			res = arrStack.cal(num1, num2, oper);
			numStack.push(res);

		}

		res = numStack.pop();
		System.out.println(expression+"=" + res);
	}

}

class ArrayStacklist1 {
	private int maxSize; // 栈的大小
	private int[] stack; // 数组,数组模拟栈,数据就放在该数组
	private int top = -1;// top表示栈顶,初始化为-1

	public ArrayStacklist1(int maxSize) {
		this.maxSize = maxSize;

		stack = new int[maxSize];
	}

	// 赋予运算符的优先级
	public int priority(int oper) {
		if (oper == '*' || oper == '/') {
			return 1;
		} else if (oper == '+' || oper == '-') {
			return 0;
		} else {
			return -1; // 假定目前的表达式只有 +, - , * , /
		}
	}

	
	// 判断是佛为运算符
	public boolean isOper(char ch) {
		return ch == '+' || ch == '-' || ch == '*' || ch == '/';
	}

	// 返回栈顶元素
	public int peek() {
		return stack[top];
	}

	
	// 运算结果
	public int cal(int num1, int num2, int oper) {
		int res = 0;
		switch (oper) {
		case '*':
			res = num1 * num2;

			break;
		case '/':
			res = num2 / num1;
			break;
		case '+':
			res = num1 + num2;
			break;
		case '-':
			res = num2 - num1;
			break;
		default:
			break;
		}
		return res;
	}

	// 是否栈满
	public boolean isFull() {
		return top == maxSize - 1;
	}

	// 是否为空
	public boolean isEmpty() {
		return top == -1;
	}

	// 入栈
	public void push(int val) {
		if (isFull()) {
			System.out.println("已经满了");
			return;
		}
		top++;
		stack[top] = val;

	}

	
	// 出栈
	public int pop() {
		if (isEmpty()) {
			throw new RuntimeException("栈空,没有数据~");

		}

		int val = stack[top];
		top--;
		return val;

	}

	// 遍历显示栈中数据
	public void show() {
		if (isEmpty()) {
			System.out.println("空数据");
			return;
		}

		for (int i = top; i >= 0; i--) {
			if (stack[i] != 0) {
				System.out.printf("stack[%d]=%d\n", i, stack[i]);
			}
		}

	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐 昊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值