基于数组实现的栈结构
package com.example.datastructures.stack;
import java.util.Scanner;
import java.util.regex.Pattern;
/**
* @author maoyouhua
* @version jdk21
*
* 基于数组实现的栈结构
*
*/
public class ArrayStack<T> {
private int top;
private final Object[] arr;
public ArrayStack(int maxSize) {
this.arr = new Object[maxSize];
}
/**
* 判断栈是否已满
*/
public boolean isFull(){
return top == arr.length;
}
/**
* 判断栈是否为空
*/
public boolean isEmpty(){
return top == 0;
}
/**
* 入栈
*/
public void push(T n){
if (isFull()) {
System.out.println("栈已满,不能添加数据");
return;
}
arr[top++] = n;
}
/**
* 出栈
*/
public T pop(){
if (isEmpty()) {
return null;
}
return (T) arr[--top];
}
/**
* 显示栈顶数据
*/
public T showTopData(){
if (isEmpty()) {
return null;
}
return (T) arr[top - 1];
}
/**
* 遍历栈
*/
public void show(){
if (isEmpty()) {
System.out.println("栈为空,不能遍历数据");
return;
}
System.out.println(arr);
}
public int size(){
return top;
}
/**
* @param args
*/
public static void main(String[] args) {
extracted();
}
private static void extracted() {
ArrayStack<Integer> arrayStack = new ArrayStack(3);
String key = "";
boolean loop = true;
Scanner scanner = new Scanner(System.in);
while (loop) {
System.out.println("show : 表示显示栈");
System.out.println("exit : 表示退出栈");
System.out.println("push : 表示添加数据到栈");
System.out.println("pop : 表示从栈取出数据");
key = scanner.next();
switch (key) {
case "show" -> arrayStack.show();
case "push" -> {
System.out.println("请输入一个数");
int value = scanner.nextInt();
arrayStack.push(value);
}
case "pop" -> {
try {
int pop = arrayStack.pop();
System.out.println("出栈的数据是:" + pop);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
case "exit" -> {
scanner.close();
loop = false;
}
}
}
System.out.println("程序已退出!!!");
}
}
栈应用之逆波兰表达式实现的整数计算器
package com.example.datastructures.stack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;
/**
* * @author maoyouhua
* * @version jdk21
* 逆波兰表达式(后缀表达式)实现的计算器
* 中缀表达式转后缀表达式
* (3 + 4) * 5 - 6 -> 3 4 + 5 * 6 -
*/
public class Calculator {
/**
* 计算表达式
* @param expression
* @return
*/
public static int calculator(String expression) {
List<String> stringList = parseSuffixExpressionList(expression);
System.out.println(stringList);
return calculate2(stringList);
}
/**
* 中缀表达式 转后缀 表达式
* 1 + ( ( 2 + 3 ) * 4) - 5 -> 1 2 3 + 4 * + 5 -
* @param infixExpression 中缀表达式
* @return
*/
public static List<String> parseSuffixExpressionList(String infixExpression){
//1. 中缀表达式转list
List<String> infixExpressionList = toInfixExpressionList(infixExpression);
//2.list转后缀表达式list
return infixToSuffix(infixExpressionList);
}
/**
* 后缀表达式计算结果
* @param ls 后缀表达式集合 3 4 + 5 * 6 -
* @return
*/
public static int calculate2(List<String> ls){
Stack<String> stack = new Stack<>();
for (String item : ls) {
if (item.matches("\\d+")) {
stack.push(item);
} else {
int res = calculate1(Integer.parseInt(stack.pop()), Integer.parseInt(stack.pop()), item);
stack.push(String.valueOf(res));
}
}
return Integer.parseInt(stack.pop());
}
/**
* 中缀表达式 转集合
* @param expression 中缀表达式
* @return
*/
public static List<String> toInfixExpressionList(String expression){
expression = expression.replaceAll(" ","");
List<String> stringList = new ArrayList<>();
StringBuilder stringBuilder = new StringBuilder();
char[] charArray = expression.toCharArray();
String[] stringArray = new String[charArray.length];
for (int i = 0; i < charArray.length; i++) {
stringArray[i] = String.valueOf(charArray[i]);
}
for (int i = 0; i < stringArray.length; i++) {
if (stringArray[i].matches("\\d+")) {
if (i == stringArray.length -1) {
stringList.add(stringArray[i]);
} else {
stringBuilder.append(stringArray[i]);
}
} else{
if (!stringBuilder.isEmpty()) {
stringList.add(stringBuilder.toString());
stringBuilder.setLength(0);
}
stringList.add(stringArray[i]);
}
}
return stringList;
}
/**
* 1 + ( ( 2 + 3 ) * 4) - 5 -> 1 2 3 + 4 * + 5 -
* 7 * 5 - 6 -> 7 5 * 6 -
* 2 + 3 * 4 -> 2 3 4 * +
* 中缀表达式list转后缀表达式list
* @param infixExpressionList
* @return
*/
public static List<String> infixToSuffix(List<String> infixExpressionList){
Stack<String> s1 = new Stack();
List<String> s2 = new ArrayList<>();
for (String item : infixExpressionList) {
if (item.matches("\\d+")) {
s2.add(item);
} else if ("(".equals(item)) {
s1.push(item);
} else if (")".equals(item)) {
while (!"(".equals(s1.peek())) {
s2.add(s1.pop());
}
s1.pop();
} else {
//说明 item 是 运算符 ,但是栈顶不一定是运算符
while (!s1.empty() && !"(".equals(s1.peek()) && !Operator.levelCompare(item, s1.peek())) {
s2.add(s1.pop());
}
s1.push(item);
}
}
while (!s1.empty() ) {
s2.add(s1.pop());
}
return s2;
}
/**
* 后缀表达式转list
* @param suffixExpression
* @return
*/
public static List<String> tosuffixExpressionList(String suffixExpression){
String[] split = suffixExpression.split(" ");
return Arrays.stream(split).collect(Collectors.toList());
}
/**
* 两个数的基础加减乘除计算
* @param num1
* @param num2
* @param opt 操作符号
* @return
*/
public static int calculate1(int num1, int num2, String opt){
int result = 0;
result = switch (opt) {
case "+" -> num2 + num1;
case "-" -> num2 - num1;
case "*" -> num2 * num1;
case "/" -> num2 / num1;
default -> throw new RuntimeException("操作符异常");
};
return result;
}
public static void main(String[] args) {
int calculator = calculator("1 + ( ( 2 + 3 + 5) * 4) - 5");
// int calculator = calculator("(2 + 3-3) * 5");
System.out.println("calculator :" + calculator);
}
}
运算符枚举类
package com.example.datastructures.stack;
/**
* @author maoyouhua
* @version jdk21
* 加减乘除操作符及优先级
*/
public enum Operator{
ADD("+",0),
SUB("-",0),
MUL("*",1),
DIV("/",1);
private String sign;
private int level;
private Operator(String sign, int level) {
this.sign = sign;
this.level = level;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public static Boolean levelCompare (String op1, String op2) {
return getInstance(op1).getLevel() > getInstance(op2).getLevel();
}
private static Operator getInstance(String operator){
return switch (operator) {
case "+" -> ADD;
case "-" -> SUB;
case "*" -> MUL;
case "/" -> DIV;
default -> throw new RuntimeException("运算符错误");
};
}
}