自定义栈实现计算器_直接处理中缀表达式

整体思路

我只实现了整数的加减乘除运算

  1. 输入一个字符串表达式
  2. 定义一个index作为索引,来遍历表达式
  3. 定义一个数栈numStack存储数字,定义一个符号栈operStack存储符号
  4. 当index指向一个数字,就判断下一位是否为数字
    若是,则拼接在一起,然后再判断下一位,直到index指向符号,则停止,并将拼接好的数字存入数栈。
  5. 当index指向一个符号,则分为以下几种情况
    5.1 若符号为 ‘(’ ,就直接存入符号栈,为后面的‘)’做准备
    5.2 若符号为 ‘)’ ,就按顺序每次从数栈取出两个数,从符号栈取出一个符号,做计算,并将计算出的结果存入数栈,直到取到 ‘(’ 为止。
    5.3 若为运算符,则与栈中运算符做比较,如果当前运算符的优先级小于等于栈中运算符,就从数栈取出两个数,从符号栈取出一个符号,做计算,并将计算出的结果存入数栈,当前运算符的优先级小于等于栈中运算符,则直接存入符号栈。
    5.4 若符号栈为空,就直接存入符号栈
  6. 当表达式遍历完,就按顺序每次从数栈取出两个数,从符号栈取出一个符号,做计算,并将计算出的结果存入数栈,直到取到符号栈为空,此时数栈就剩下一个数字,就是最终结果。

废话不多说,上代码

代码实现

import java.util.Scanner;

public class Calculator1 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		//输入表达式
		String expression = sc.next();
		sc.close();
		//定义两个栈,一个数栈,一个符号栈
		MyStack numStack = new MyStack(20);
		MyStack operStack = new MyStack(20);
		//定义用于做计算的符号,数1,数2,结果
		int oper = 0, num1 = 0, num2 = 0, result = 0;
		//定义表达式的索引
		int index = 0;
		//遍历表达式
		while (index < expression.length()) {
			char ch = expression.charAt(index);
			//判断是否为符号
			if (isOper(ch)) {
				//判断是否为')'
				if (ch == ')') {
					//按顺序每次从数栈取出两个数,从符号栈取出一个符号做计算
					//并将计算出的结果存入数栈,直到取到 '(' 为止
					while (true) {
						//从符号栈取出一个符号
						oper = operStack.pop();
						if (oper == '(') {
							break;
						}
						//从数栈取出两个数
						num1 = numStack.pop();
						num2 = numStack.pop();
						//计算
						result = cal(num1, num2, oper);
						//将计算出的结果存入数栈
						numStack.push(result);
					}
				} else {
					//判断符号栈是否为空,扫描到的符号是否为'(',以及比较当前运算符和栈中运算符的优先级
					if (ch != '(') {
						while (!operStack.isEmpty() && getPriority(ch) <= getPriority(operStack.peekTop())) {
							oper = operStack.pop();
							num1 = numStack.pop();
							num2 = numStack.pop();
							result = cal(num1, num2, oper);
							numStack.push(result);
						}
					}
					operStack.push(ch);
				}
			} else {
				String num = "" + ch;
				//扫描到数字,依次拼接相邻的数字
				while (index + 1 < expression.length() && !isOper(expression.charAt(index + 1))) {
					num += expression.charAt(++index);
				}
				numStack.push(Integer.parseInt(num));
			}
			index++;
		}
		//表达式遍历完毕,依次取剩下的数字和符号做计算
		while (!operStack.isEmpty()) {
			num1 = numStack.pop();
			num2 = numStack.pop();
			oper = operStack.pop();
			result = cal(num1, num2, oper);
			numStack.push(result);
		}
		result = numStack.pop();
		System.out.println(expression + "=" + result);
	}
	/**
	 * 做计算
	 * @param num1	数1
	 * @param num2	数2
	 * @param oper	符号
	 * @return		结果
	 */
	private static int cal(int num1, int num2, int oper) {
		int result = 0;
		switch (oper) {
		case '+':
			result = num2 + num1;
			break;
		case '-':
			result = num2 - num1;
			break;
		case '*':
			result = num2 * num1;
			break;
		case '/':
			result = num2 / num1;
			break;
		default:
			break;
		}
		return result;
	}
	/**
	 * 获取到符号的优先级,优先级自定义
	 * @param oper	符号
	 * @return	返回优先级
	 */
	private static int getPriority(int oper) {
		if (oper == '+' || oper == '-') {
			return 1;
		}
		if (oper == '*' || oper == '/') {
			return 2;
		}
		return 0;
	}
	/**
	 * 判断所扫描到的字符是否为符号
	 * @param ch
	 * @return
	 */
	private static boolean isOper(char ch) {
		if (ch >= '0' && ch <= '9') {
			return false;
		}
		return true;
	}
}
//自定义栈结构
class MyStack {
	private int maxSize;	//存储栈的大小
	private int[] stack;	//存储数据
	private int top = -1;	//栈顶指针
	//构造器
	public MyStack(int maxSize) {
		this.maxSize = maxSize;
		stack = new int[maxSize];
	}
	//栈满
	public boolean isFull() {
		return top == maxSize - 1;
	}
	//栈空
	public boolean isEmpty() {
		return top == -1;
	}
	//入栈
	public boolean push(int value) {
		if (isFull()) {
			System.err.println("栈满,无法存入~");
			return false;
		}
		stack[++top] = value;
		return true;
	}
	//出栈,返回栈顶数据
	public int pop() {
		if (isEmpty()) {
			throw new RuntimeException("栈空,没有数据~");
		}
		return stack[top--];
	}
	//查看栈顶数据,但不取出,用于判断优先级
	public int peekTop() {
		return stack[top];
	}
	//遍历栈,列出全部数据
	public void list() {
		if (isEmpty()) {
			System.err.println("栈空,没有数据~");
			return;
		}
		for (int i = top; i >= 0; i--) {
			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、付费专栏及课程。

余额充值