栈实现综合计算器

本文详细介绍了如何使用栈数据结构实现一个综合计算器,涵盖了数字压栈、符号处理以及运算优先级的判断。通过示例代码展示了一个基于双向链表的栈实现,并提供了测试用例进行验证。此外,还讨论了用数组实现栈的备选方案。
摘要由CSDN通过智能技术生成

栈实现综合计算器

最近在学习数据结构与算法的时候碰到了一个问题用栈实现综合计算器,发现网上还没有一个相对好理解的版本,所以有了这篇文章。
思路

数字直接压数栈
符号分情况,如果符号栈内无元素,直接压栈
如果有元素啧对比,如果当前符号优先级大于栈内所有元素,那么直接压栈
如果小于或等于,那么先运算栈内符号,这里有坑,要注意,用while来代替if(因为不止有一个需要判断)

//先来一个栈的接口
public interface Stack<T> {

	T pop();

	void push(T t);

	T peek();

}
//定义节点
public class Node<T>{
	T value;
	Node<T> left;
	Node<T> right;

	public Node() {
	}

	public Node(T value) {
		this.value = value;
	}

	public Node(T value, Node<T> left, Node<T> right) {
		this.value = value;
		this.left = left;
		this.right = right;
	}
}
//用双向链表来实现一个栈
public class LinkedStackDemo<T> implements Stack<T>{

	private Node<T> first;

	@Override
	public T pop() {
		if(first == null){
			throw new NullPointerException("栈顶无元素!!");
		}
		Node<T> temp = first;
		if(first.right != null){
			first.right.left = null;
		}
		first = first.right;

		return temp.value;
	}

	@Override
	public void push(T t) {
		Node add = new Node(t);
		if(first == null){
			first = add;
			return;
		}
		add.right = first;
		first.left = add;
		first = add;
	}

	@Override
	public T peek() {
		if(first == null){
			return null;
		}
		Node<T> temp = first;
		return temp.value;
	}

}
//计算器的实现
public class Calculator {

	private static final List<Character> SYMBOL = Arrays.asList('+', '-', '*', '/');
	private static final List<Character> SYMBOL2 = Arrays.asList('(', ')');
	private static final Map<Character, Integer> LEVEL = new HashMap<Character, Integer>() {{
		put('(', 1);
		put('+', 8);
		put('-', 9);
		put('*', 10);
		put('/', 11);
	}};


	//思路
	//数字直接压数栈
	//符号分情况,如果符号栈内无元素,直接压栈
	//如果有元素啧对比,如果当前符号优先级大于栈内所有元素,那么直接压栈
	//如果小于或等于,那么先运算栈内符号,这里有坑,要注意,用while来代替if(因为不止有一个需要判断)
	public BigDecimal exec(String expression) {
		char[] chars = expression.toCharArray();
		Stack<BigDecimal> numStack = new LinkedStackDemo<>();
		Stack<Character> symbolStack = new LinkedStackDemo<>();

		StringBuffer numTemp = new StringBuffer();
		for (char aChar : chars) {

			if (SYMBOL.contains(aChar)) {
				this.numberFormat(numStack, numTemp);

				if (symbolStack.peek() == null) {
					symbolStack.push(aChar);
				} else {
					while (symbolStack.peek() != null && LEVEL.get(aChar) <= LEVEL.get(symbolStack.peek())){
						this.jisuan2(numStack, symbolStack);
					}
					symbolStack.push(aChar);
				}
			} else if (SYMBOL2.contains(aChar)) {
				this.numberFormat(numStack, numTemp);
				if (aChar == ')') {
					while (symbolStack.peek() != '(') {
						this.jisuan2(numStack, symbolStack);
					}
					symbolStack.pop();
				} else {
					symbolStack.push(aChar);
				}
			} else {
				numTemp.append(aChar);
			}

		}
		this.numberFormat(numStack, numTemp);

		while (symbolStack.peek() != null) {
			this.jisuan2(numStack, symbolStack);
		}

		return numStack.pop();
	}

	private void numberFormat(Stack<BigDecimal> numStack, StringBuffer numTemp) {
		if (numTemp.length() != 0) {
			BigDecimal bigDecimal = new BigDecimal(numTemp.toString());
			numStack.push(bigDecimal);
			numTemp.delete(0, numTemp.length());
		}
	}

	private void jisuan2(Stack<BigDecimal> numStack, Stack<Character> symbolStack) {
		BigDecimal right = numStack.pop();
		BigDecimal left = numStack.pop();
		BigDecimal jisuan = jisuan(left, right, symbolStack.pop());
		numStack.push(jisuan);
	}

	private BigDecimal jisuan(BigDecimal left, BigDecimal right, char symbol) {
		switch (symbol) {
			case '+': {
				return left.add(right);
			}
			case '-': {
				return left.subtract(right);
			}
			case '*': {
				return left.multiply(right);
			}
			case '/': {
				return left.divide(right);
			}
			default: {
				throw new RuntimeException("无效的类型!");
			}
		}
	}

}
//测试用例
public class Test {
	public static void main(String[] args) {

		Calculator calculator = new Calculator();
		System.out.println(calculator.exec("7-6-1-8"));

	}
}
//也可以用数组来实现一个栈
public class ArrayStackDemo<T> implements Stack<T> {

	private Object[] elements;
	private int size;
	private int max;

	public ArrayStackDemo() {
		this.elements = new Object[10];
		this.max = 10;
	}

	@Override
	public T pop() {
		if(size == 0){
			throw new NullPointerException("栈内无元素!");
		}
		return (T)elements[--size];
	}

	@Override
	public void push(T t) {
		if(size >= max){
			max = max * 2;
			Object[] objects = new Object[max];
			System.arraycopy(elements, 0, objects, 0, size);
			elements = objects;
		}
		elements[size++] = t;
	}

	@Override
	public T peek() {
		if(size == 0){
			return null;
		}
		return (T)elements[size - 1];
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值