栈

基本介绍

应用场景


实现思路

计算器实现

package com.company.stack;
import com.sun.source.tree.TryTree;
import java.util.Stack;
/**
* @Function :
* date 2021/5/9 - 14:12
* How :
*/
public class Calculator {
public static void main(String[] args) {
String exp = "10+100/10";
char[] expression = exp.toCharArray();
ArrayStackCalculater numberStack = new ArrayStackCalculater(10);
ArrayStackCalculater operStack = new ArrayStackCalculater(10);
//用于扫描的变量
int index = 0;
int number1 = 0;
int number2 = 0;
int oper = 0;
int result = 0;
char ch = ' '; //保存每次扫描的char
String keepNum = "";
while (true){
ch = expression[index];
if (operStack.isOper(ch)){
if (!operStack.isEmpty()){
//不为空
//如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数,
//在从符号栈中pop出一一个符号,进行运算,将得到结果,入数栈,然后将当前的操作符入符号栈
if (operStack.priority(ch)<=operStack.priority(operStack.peek())){
number1 = numberStack.pop();
number2 = numberStack.pop();
oper = operStack.pop();
result = numberStack.calculate(number2,number1,oper);
numberStack.push(result);
operStack.push(ch);
}else {
operStack.push(ch);
}
}else {
//为空 直接入栈
operStack.push(ch);
}
}else {
//数字 入数栈
//numberStack.push(ch-48);
//分析
//1. 当处理多位数时候 不能发现一位数就直接入栈
//2. 在处理数字时候 需要向表达式后多看一位
//3. 定义一个字符串变量 用于拼接
keepNum+=ch;
//最后一位i 直接入栈
if (index == expression.length-1){
numberStack.push(Integer.parseInt(keepNum));
//清空num
keepNum="";
}else {
if (operStack.isOper(expression[index+1])){
numberStack.push(Integer.parseInt(keepNum));
keepNum="";
}
}
}
index ++;
if (index>=expression.length){
break;
}
}
//出栈 运算
while (true){
if (operStack.isEmpty()){
break;
}
number1 = numberStack.pop();
number2 = numberStack.pop();
oper = operStack.pop();
result = numberStack.calculate(number2,number1,oper);
numberStack.push(result);
}
System.out.printf("结果是:%d",result);
}
}
class ArrayStackCalculater{
private int maxSize;
private int[] stack;
private int top;
public ArrayStackCalculater(int maxSize) {
this.maxSize = maxSize;
this.top = -1;
this.stack = new int[maxSize];
}
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 (this.isFull()){
System.out.println("栈满");
return;
}
top++;
stack[top]=value;
}
public int pop(){
if (this.isEmpty()){
throw new RuntimeException("栈空");
}
int value = stack[top];
top--;
return value;
}
public void showStack(){
if (this.isEmpty()){
throw new RuntimeException("栈空");
}
for (int i = top; i >-1 ; i--) {
System.out.printf("---%d",stack[i]);
}
}
//返回优先级 优先级使用数字表示
public int priority(int oper){
if (oper == '*' || oper == '/'){
return 1;
}else if (oper == '+' || oper == '-'){
return 0;
}else {
System.out.println("目前只有 + - * /");
return -1;
}
}
//判断是不是运算符
public boolean isOper(char val){
return val=='+' || val=='-' || val=='*' || val=='/';
}
//计算方法
public int calculate(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;
default:
break;
}
return res;
}
}
表达式
前缀表达式(波兰表达式)

中缀表达式

后缀表达式(逆波兰)


应用(逆波兰计算器)

package com.company.stack;
import java.beans.Expression;
import java.util.List;
import java.util.Stack;
/**
* @Function :
* date 2021/5/9 - 15:50
*
* How :
*/
public class PolandNotation {
public static void main(String[] args) {
//给定逆波兰表达式
// (3+4)*5-6 ===》 3 4 + 5 * 6 -
String suffixExpression = "3 4 + 10 * 6 -";
String[] suffixExp = suffixExpression.split(" ");
int a = calculate(suffixExp);
System.out.printf("计算的结果:a=%d",a);
}
public static int calculate( String[] lis){
//创建给栈,只需要一个栈即可
Stack <String> stack = new Stack<String>();
//遍历ls
for(String item: lis){
//这里使用正则表达式来取出数
if (item.matches("\\d+")) { //匹配的是多位数
//入栈
stack.push(item);
}else {
int num1 = Integer.parseInt(stack.pop());
int num2 = Integer.parseInt(stack.pop());
int res = 0;
if (item.equals("+")){
res = num1+num2;
}else if (item.equals("-")){
res = num2 - num1;
}else if (item.equals("*")){
res = num1*num2;
}else if (item.equals("/")){
res = num2/num1;
}else {
throw new RuntimeException("输入符号错误");
}
stack.push(String.valueOf(res));
}
}
return Integer.parseInt(stack.pop());
}
}