JAVA 数据结构学习-06 栈
JAVA 数据结构-06 (1)栈的基本数据结构实现(数组实现,链表实现)
JAVA 数据结构-06 (3) 栈结构的应用 前 中 后缀三种表达式 中缀表达式转后缀表达式 逆波兰计算器实现和算法思路
2. 栈结构的应用(表达式与计算器)
2.1 简易计算表达式的计算(中缀表达式)
70*2*2-5+1-5-3+4
实现思路:
- 设置2个栈结构,一个数栈numStack只用来保存数字;一个符号栈operStack只用来保存符号.
- 通过一个index值来遍历我们的表达式;
- 如果发现index值是一个数字,就直接入符号栈;
- 如果发现扫描到一个符号:分为一下三种情况:
- 如果符号栈为空,就直接入栈
- 如果符号栈不为空且当前index扫描的操作符优先级小于或等于栈顶的操作符,就需要从数栈中pop出2个数据,从符号栈中pop出一个符号,执行二元运算(减法和除法需要注意谁减/除谁);将得到的结果入数栈,然后在将当前操作符压入符号栈中.
- 如果符号栈不为空且当前index扫描的操作符优先级大于栈顶的操作符,就直接入栈.
- 当表达式扫描完毕时,数栈中会存储表达式中的数字和优先级较高的运算中间量,符号栈中会存储优先级从栈顶开始递减的操作符;
- 因此可用直接按符号栈的顺序进行计算,顺序的从符号栈中pop出一个操作符,从数栈中pop出2个数字,执行完运算后将运算结果压回数字栈;
- 当操作符栈为空时,数栈中栈顶的数字就是最终运算结果.
准备栈结构:(java底层会将char转换为int,因此可以直接比较char和int)
添加判断是否是 操作符, 优先级, 执行计算 三个方法
class ArrayStack {
private int maxSize;
private int stack[];
private int top = -1;
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
this.stack = new int[maxSize];
}
public boolean isFull() {
return top == maxSize - 1;
}
public boolean isEmpty() {
return top == -1;
}
public int getTop(){
if(isEmpty()){
throw new RuntimeException("栈空");
}
return stack[top];
}
public void push(int data){
if(isFull()){
System.out.println("栈满,无法压入数据");
return;
}
top++;
stack[top] = data;
}
public int pop(){
if(isEmpty()){
throw new RuntimeException("栈为空,无法取出数据");
}
int value = stack[top];
top --;
return value;
}
public void showStack(){
if(isEmpty()){
System.out.println("栈为空");
return ;
}
for (int i = top; i >=0 ; i--) {
System.out.printf("stack[%d] = %d \n",i,stack[i]);
}
}
//判断是否是操作符
//char 底层也是转换为int 所有可用直接进行比较
public boolean isOper(int value){
return value == '+' || value == '-' || value == '*' || value == '/';
}
//返回操作符的优先级 */优先级高于+-
public int priority(int value){
if(value == '*' || value == '/'){
return 1;
}
if(value == '+' || value == '-'){
return 0;
}
return -1;
}
//执行计算
public int calculation (int num1,int num2,int oper){
int res = 0;
switch (oper){
case '+':
res = num1 + num2;
break;
case '-':
res = num1 - num2;
break;
case '*':
res = num1 * num2;
break;
case '/':
res = num1 / num2;
break;
}
return res;
}
}
思路实现:
public class Caculator {
public static void main(String args[]){
//1.创建过程中需要使用的变量
ArrayStack numStack = new ArrayStack(10);
ArrayStack operStack = new ArrayStack(10);
String expression = "70+2*6-4";
int num1;
int num2;
int oper;
int res = 0;
int index = 0;
char ch = ' ';
String number= "";
while (true){
//获取ch
ch = expression.charAt(index);
if(numStack.isOper(ch)){
//是符号进行下一步判断
if(operStack.isEmpty()){
//直接进栈
operStack.push(ch);
}else {
if(operStack.priority(ch) <= operStack.priority(operStack.getTop())){
//需要从数栈中pop出2个数据,从符号栈中pop出一个符号,执行二元运算(减法和除法需要注意谁减/除谁);
//将得到的结果入数栈,然后在将当前操作符压入符号栈中.
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.calculation(num2, num1,oper);
numStack.push(res);
operStack.push(ch);
}else {
// 直接入栈.
operStack.push(ch);
}
}
} else {
number += ch;
if(index == expression.length() -1){
numStack.push(Integer.parseInt(number));
}else {
//处理多位数,需要看index位置的后一位是否还是数字,如果是,就需要进行拼接.如果是操作符,则直接入栈
if(operStack.isOper(expression.charAt(index+1))){
//直接将string入栈
numStack.push(Integer.parseInt(number));
number = "";
}
}
}
index++;
if(index >= expression.length()){
break;
}
}
//数据处理完成.执行计算
while (true){
if(operStack.isEmpty()) break;
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.calculation(num2, num1,oper);
numStack.push(res);
}
System.out.println("最后的计算结果为:"+numStack.pop());
}
}