实现原理:
/** * 1.遍历字符串,获取每一个字符 * 2.判断是一个字符还是个数字 * 3.把数字放在数字栈中,把运算符放在运算符栈中 * 4.运算符栈:如果是一个空栈,直接入栈,如果已经存在其他运算符,则需要对比运算符优先级。 * 新进来的运算符如果小于等于原栈中的运算符,则需要把原运算符弹栈,数字栈中数字进行弹栈, * 进行运算,运算后的结果,重新放入数字栈,新运算符入栈。 * 如果新的运算符,优先级大于原符号栈中的运算符,那么新的符号直接入栈。 */
通过栈原理实现-工具类:
package controller.Algorithm;
public class ArrayStack {
// 栈的大小
private int maxStack;
// 模拟栈
private int[] stack;
// 栈顶所在位置,默认为-1
private int top =-1;
//
public ArrayStack(int maxStack){
this.maxStack=maxStack;
stack = new int[maxStack];
}
/**
* 1.压栈
* 2.弹栈
* 3.判断是否是空值
* 4.是否是满栈状态
*/
/*
*判断是否是满栈
*/
public Boolean isFull(){
return this.top==this.maxStack-1;
}
/*
*判断是否是满栈
*/
public Boolean isEmpty(){
return this.top==-1;
}
/*
*压栈
*/
public void push(int val){
// 是否已经占满
if(isFull()){
throw new RuntimeException("此栈已满");
}
top++;
stack[top]=val;
}
/*
*弹栈
*/
public int pop(){
if(isEmpty()){
throw new RuntimeException("空栈");
}
int value = stack[top];
top--;
return value;
}
/*
*查看栈中所有元素
*/
public void list(){
if(isEmpty()){
throw new RuntimeException("空栈,未找到数据");
}
for (int i=0;i<stack.length;i++){
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
/**
* 栈中元素存在的个数
* @return 栈中元素存在的个数
*/
public int length(){
return this.top+1;
}
/**
* 判断是否是一个运算符 + - * /
* @return 栈中元素存在的个数
*/
public boolean isOper(char v){
return v=='+'||v=='-'||v=='*'||v=='/';
}
/**
* 判断运算符优先级,用数字表示优先级大小,数字越大优先级越大
*/
public int priority(int oper){
if(oper=='*'||oper=='/'){
return 1;
} else if(oper=='+'||oper=='-'){
return 0;
}else {
return -1;
}
}
/**
* 获取栈顶数据
*/
public int peek(){
return this.stack[top];
}
/**
* 获取栈的容量
*/
public int stackLength(){
return this.stack.length;
}
/**
* 计算两个数运算后的结果
*/
public int calculate(int num1,int num2,int oper){
//计算结果
int result = 0;
switch (oper){
case '+':
result= num1+num2;
break;
case '-':
result= num2-num1;
break;
case '*':
result= num2*num1;
break;
case '/':
result= num2/num1;
break;
}
return result;
}
}
调用代码:
package controller.Algorithm;
public class TestStack {
public static void main(String[] args) {
String str = "4+3+2*3-1";
/**
* 1.遍历字符串,获取每一个字符
* 2.判断是一个字符还是个数字
* 3.把数字放在数字栈中,把运算符放在运算符栈中
* 4.运算符栈:如果是一个空栈,直接入栈,如果已经存在其他运算符,则需要对比运算符优先级。
* 新进来的运算符如果小于等于原栈中的运算符,则需要把原运算符弹栈,数字栈中数字进行弹栈,
* 进行运算,运算后的结果,重新放入数字栈,新运算符入栈。
* 如果新的运算符,优先级大于原符号栈中的运算符,那么新的符号直接入栈。
*/
ArrayStack numStack = new ArrayStack(10);
ArrayStack symbolStack = new ArrayStack(10);
/**
* 获取字符串的长度
*/
int temp1 = 0;
int temp2 = 0;
int symbolChar = 0;
int result = 0;
int length = str.length();
String values = "";
for (int i = 0; i < length; i++) {
char c = str.charAt(i);
/**
* 是否是一个运算符
*/
if (symbolStack.isOper(c)) {
/**
* 如果不是一个空栈
*/
if (!symbolStack.isEmpty()) {
// 比较运算符的优先级
if (symbolStack.priority(c) < symbolStack.priority(symbolStack.peek())) {
/**
* 1.去符号栈中获取栈顶符号
* 2.去数字栈中获取两个数字
*/
temp1 = numStack.pop();
temp2 = numStack.pop();
symbolChar = symbolStack.pop();
int calculate = numStack.calculate(temp1, temp2, symbolChar);
// 把计算结果放入数字栈中
numStack.push(calculate);
// 把当前结果压入符号栈
symbolStack.push(c);
} else {
symbolStack.push(c);
}
} else {
// 如果是空符号栈,将运算符直接压栈
symbolStack.push(c);
}
} else {
// 比如33+44
values += c;
// 如果是最后一位
if (i == length - 1) {
numStack.push(Integer.valueOf(values));
} else {
// 如果不是最后一位,需要判断数字的个数进行拼接
char c1 = str.substring(i + 1, i + 2).charAt(0);
if (symbolStack.isOper(c1)) {
numStack.push(Integer.valueOf(values));
// 放入之后values要清空
values = "";
}
}
}
}
while (true) {
// 如果栈中已经为空则不需要计算
if (symbolStack.isEmpty()) {
break;
}
temp1 = numStack.pop();
temp2 = numStack.pop();
symbolChar = symbolStack.pop();
// 将两个数据进行计算
result = numStack.calculate(temp1, temp2, symbolChar);
// 将结果再次压入到栈中,最后只剩一个数据
numStack.push(result);
}
int res = numStack.pop();
System.out.println("结果是"+res);
}
}
最终结果: