思路分析:
直接上代码吧
定义好拥有功能扩张的栈
/**
* 需要扩张功能
*/
class ArrayStack2 {
/**
* top 数组指针 一直指向尾部 初始值为-1 stack 为存数据的数组 maxSize 数组的最大容量
*/
private int top = -1;
private int[] stack;
private int maxSize;
/**
* 构造器 用来构造数据
*
* @param maxSize
*/
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
}
/**
* 增加一个方法查看栈顶 不是去除
*/
public int peek(){
return stack[top];
}
/**
* 判断数组是否满了 尾部指针等于最大容量减一为满
*
* @return
*/
public boolean isFull() {
return top == maxSize - 1;
}
/**
* 判断数据是否为空 尾部指针指向头部 没有一个数据
*/
public boolean isEmpty() {
return top == -1;
}
/**
* 添加方法
*
* @param value
*/
public void push(int value) {
// 先判断栈是否满了
if (isFull()) {
System.out.println("栈满了");
return;
}
// 指针后移 添加数据
top++;
stack[top] = value;
}
/**
* 去除方法 不是真正意义上的移除 只是让指针向前走 移除以后再添加 属于覆盖之前的值
*
* @return
*/
public int pop() {
// 先判断是否是空栈
if (isEmpty()) {
throw new RuntimeException("栈空");
}
// 返回最后一个数 让指针向前走
int value = stack[top];
top--;
return value;
}
/**
* 循环遍历数组
*/
public void list() {
// 判断数组是否为空
if (isEmpty()) {
System.out.println("栈空");
return;
}
// 让i=top 帮助去遍历 top的值不用变
for (int i = top; i > -1; i--) {
System.out.println(stack[i]);
}
}
/**
* 返回运算符的优先级 优先级是由程序员定 使用数字表示方便 数字越大 优先级越高
* 目前表达式只有加减乘除
*/
public int priority(int operator){
//给运算符号分配级别
if (operator=='*' || operator=='/'){
return 1;
}
else if (operator=='+' || operator=='-'){
return 0;
}
else {
return -1;
}
}
/**
* 判断是不是一个运算符
* 不是运算符就是数字
* @return
*/
public boolean isOperator(char val){
return val == '+'||val=='-'|| val == '/' || val=='*';
}
/**
* 计算方法
*/
public int cal(int num1,int num2,int operator){
int res = 0;
switch (operator){
case '+':
res=num1+num2;
break;
case '*':
res=num1*num2;
break;
case '/':
res=num1/num2;
break;
case '-':
res=num1-num2;
break;
default:
break;
}
return res;
}
}
测试代码
public static void main(String[] args) {
String expression = "300-2*6";
ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operatorStack = new ArrayStack2(5);
//假设遍历多位数 用于拼接
String keepStr = "";
//遍历字符串
int index = 0;
//取出的计算的两个值
int num1;
int num2;
//运算符号
int operator;
//运算结果
int res ;
//接收遍历出来的每个字符
char ch ;
//循环遍历
while (true){
//substring 第一个参数是从哪个开始第二个参数是到哪个 charAt取出字符串的第一个字符
ch = expression.substring(index,index+1).charAt(0);
//判断取出的ch是不是运算符号
if (operatorStack.isOperator(ch)){
//假如这时候运算栈不是空的
if (!operatorStack.isEmpty()){
//比较这个运算符跟运算栈中的顶层的符号的优先级
//假如遍历出来的运算符优先级小于顶层优先级别 就算出 现在顶层的运算符在放遍历出来的运算符
if (operatorStack.priority(ch)<=operatorStack.priority(operatorStack.peek())){
//拿出两个数据
num1=numStack.pop();
num2=numStack.pop();
//拿出优先级大的运算符
operator = operatorStack.pop();
//将运算级别大的运算出来再放进去
res = numStack.cal(num1,num2,operator);
numStack.push(res);
//然后将运算级别小的放进去
operatorStack.push(ch);
}else {
//假如运算级别大就直接放入等待低一级别的出现再拿出
operatorStack.push(ch);
}
}else {
//假如运算符栈是空的直接放入
operatorStack.push(ch);
}
}else {
//假如遍历出来一直是数字就一直拼接
keepStr=keepStr+ch;
//假如遍历出数字直接放入
//假如是多位数 所以要进行判断
//到了最后一位就不往下判断 直接放入
if(index==expression.length()-1){
numStack.push(Integer.parseInt(keepStr));
}else {
//假如数字下一个不是数字就不拼接了 直接放入
if (operatorStack.isOperator(expression.substring(index+1,index+2).charAt(0))){
numStack.push(Integer.parseInt(keepStr));
//放入之后将字符串初始化 相当于一个容器
keepStr="";
}
}
}
index++;
//当遍历玩直接结束开始运算低级别的运算符
if (index >=expression.length()){
break;
}
}
while(true){
//如果符号栈为空则 计算结束 数栈只有一个结果
if (operatorStack.isEmpty()){
break;
}
//拿到运算级别大的算出来的数去跟运算级别小的做运算
num2=numStack.pop();
num1=numStack.pop();
//取出运算符
operator = operatorStack.pop();
res = numStack.cal(num1,num2,operator);
numStack.push(res);
}
System.out.println(numStack.pop());
}
}