赞
踩
之前的博客已经介绍了栈数据结构,栈有着数据先进后出的特点,因此用于实现简易计算器时相当方便。本博文中将介绍如何用栈实现一个可以进行简单四则运算不含括号的简易计算器(中缀表达式)
用之前的方法用数组模拟栈
class CalculatorStack { private int maxSize; private int[] stack; private int top = -1; public CalculatorStack(int maxSize) { this.maxSize = maxSize; stack = new int[maxSize]; } /** * * @return 返回栈顶的数据<不弹出数据> */ public int peek() { return stack[top]; } public boolean isFull() { return top == maxSize - 1; } public boolean isEmpty() { return top == -1; } public void push(int value) { if (isFull()) { throw new RuntimeException("栈满无法添加数据...."); } top++; stack[top] = value; } public int pop() { if (isEmpty()) { throw new RuntimeException("栈空无法返回数据...."); } return stack[top--]; } }
/** * 返回运算符的优先级 * @param operation * @return 返回数字代表优先级 数字越大优先级越高 */ public int getPriority(int operation) { if (operation == '*' || operation == '/') { return 1; } else if (operation == '+' || operation == '-') { return 0; }else { throw new RuntimeException("输入操作符有误!"); } } /** * 判断是否是运算符 * @param val * @return */ public boolean isOperation(int val) { return val == '+' || val == '-' || val == '*' || val == '/'; } private int calculate(int num1,int num2,int operation) { int result = 0; switch (operation) { case '+': result = num2 + num1; break; case '-': //注意顺序 result = num2 - num1; break; case '*': result = num2 * num1; break; case '/': //注意顺序 result = num2 / num1; break; } return result; }
核心方法
public static void calculate(String expression) { //创建两个栈 一个数栈 一个符号栈 CalculatorStack numStack = new CalculatorStack(2002); CalculatorStack operationStack = new CalculatorStack(519); //定义相关变量 int index = 0; int num1,num2,result; int operation; //用于拼接多位数 String keepNum = ""; while (true) { //依次得到expression中的每一个字符 char ch = expression.substring(index, index + 1).charAt(0); //如果是运算符 if (operationStack.isOperation(ch)) { //判断符号栈是否为空 if (!operationStack.isEmpty()) { //如果当前操作符优先级大于栈中的所有操作符,直接入栈 if (operationStack.getPriority(ch) > operationStack.getPriority(operationStack.peek())) { operationStack.push(ch); } //如果当前操作符的优先级小于或等于栈中的操作符,先弹出符号栈栈顶的操作符和数栈的头两个数据 else { num1 = numStack.pop(); num2 = numStack.pop(); operation = operationStack.pop(); result = numStack.calculate(num1,num2,operation); //运算结果入数栈 numStack.push(result); //符号ch入符号栈 operationStack.push(ch); } }else { //符号栈为空直接入栈 operationStack.push(ch); } } //如果是数直接入数栈 else { //1.当处理多位数时,不可以直接入栈,可能是多位数 //2.处理多位数时需要看expression表达式index位置的后一位是什么,如果是数字需要继续读取否则直接入栈 //3.因此需要定义一个变量字符串用于拼接数字 keepNum+=ch; //如果当前处于表达式的末尾 if (index == expression.length() - 1) { numStack.push(Integer.parseInt(keepNum)); keepNum = ""; }else { //判断下一位是否是字符 if (operationStack.isOperation(expression.substring(index+1,index+2).charAt(0))) { numStack.push(Integer.parseInt(keepNum)); //重置keepNum!!!!! keepNum = ""; } //1 != '1' ---> 1 = '1' - 48; //numStack.push(ch - 48); } } //让index+1,并且判断是否扫描到expression最后 index++; if (index >= expression.length()) { break; } } //当表达式扫描完毕就顺序地从数栈和符号栈中取出相应的数和符号 while (true) { //如果符号栈为空--->计算完毕 if (operationStack.isEmpty()) { break; } num1 = numStack.pop(); num2 = numStack.pop(); operation = operationStack.pop(); result = numStack.calculate(num1,num2,operation); numStack.push(result); } result = numStack.pop(); System.out.printf("表达式:%s=%d",expression,result); }
public class Calculator
{
public static void main(String[] args)
{
String expression = "100+20*2-4";
CalculatorStack.calculate(expression);
}
}
//-----------------------------------------------------测试结果----------------------------------------------------
表达式:100+20*2-4=136
以上。
如有不足或错误欢迎评论指正
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。