目录
一、手动实现及栈介绍
package com.algorithm.stack;
/**
* 栈 : 后进先出 LIFO
* 使用场景:1、如何校验校验数据的 符号前后是否匹配 比如idea里 输入 ‘{}’ 是如何校验前后一致
* 2、浏览器后退及前进的实现
* 栈代码实现可以使用 数组、链表都可以
* 栈对外暴露的接口功能简单,操作较少 只能入栈及出栈,极高的提升了使用的安全性;
* @param <E>
* IStack 自行实现即可
*/
public class StackTest<E> implements IStack<E>{
private E[] items;
private int n;
public StackTest(int cap){
this.items = (E[]) new Object[cap];
}
@Override
public void push(E item) {
judgeSize();
items[n++] = item;
}
public void judgeSize(){
if(n >= this.items.length){
// 扩容
resize(items.length * 2);
}else if(n > 0 && n < items.length / 2){ // 缩容
resize(items.length / 2);
}
}
public void resize(int cap){
E[] item = (E[]) new Object[cap];
for(int i = 0; i< this.items.length; i++){
item[i]=this.items[i];
}
items = item;
}
@Override
public E pop() {
if(isEmpty()){
return null;
}
E item = items[--n];
// 弹出后将item[n] 设置为空
items[n]=null;
return item;
}
@Override
public boolean isEmpty() {
return n == 0;
}
}
二、栈实现括号匹配
package com.algorithm.stack;
import java.util.Scanner;
/**
*
* 栈实现括号匹配
* 输入: { [ ] } 正确匹配
* 输入: { [ } 错误匹配
*
*/
public class BracketsMatching {
public static void main(String[] args) {
IStack<String> stack = new StackTest<>(10);
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
do{
switch (str) {
// 入栈
case "{" :
stack.push(str);
break;
// 入栈
case "[":
stack.push(str);
break;
case "}":
String pop = stack.pop();
if(!pop.equals("{")){
throw new RuntimeException("in brackets error");
}
System.out.println("match success");
break;
case "]":
String pop1 = stack.pop();
if(!pop1.equals("[")){
throw new RuntimeException("in brackets error");
}
System.out.println("match success");
break;
default:
break;
}
} while((str= scanner.next())!=null);
}
}
三、用栈实现简单的数学公式计算
package com.algorithm.stack;
import cn.hutool.core.util.NumberUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 栈实现计算器
* 以最简单的例子来做介绍 + - * / 四个符号
* 思路: 1、创建两个栈,一个放数据,一个放符号
* 2、当匹配到数字时进行入栈
* 3、当匹配到符号时 把栈顶的符号取出
* 4、判断优先级
* 5、如果优先级比栈顶的符号优先级高则将当前符号进行入栈
* 6、如果优先级比栈顶的符号优先级低则将数字栈中取出两个
* 7、将符号栈取出栈顶进行计算
* 8、计算完成后放入栈中
*/
public class StackImplementationSimpleCalculator {
// 一下代码实现思路还待优化
public static void main(String[] args) {
// 构建计算公式
List<String> formula = new ArrayList<>();
formula.add("1");
formula.add("+");
formula.add("98");
formula.add("*");
formula.add("8");
formula.add("+");
formula.add("88");
formula.add("/");
formula.add("4");
// 数字
Stack<String> numberStack = new Stack<>();
// 符号
Stack<String> symbolStack = new Stack<>();
// 处理计算公式
for (String s : formula) {
if(NumberUtil.isNumber(s)){
numberStack.push(s);
continue;
}
// 判断是否是符号
if(SymbolPriority.judgeSymbol(s)){
// 与栈顶的符号进行比较
boolean empty = symbolStack.empty();
if(empty){
symbolStack.push(s);
}else{
// 取出栈顶进行匹配
String pop = symbolStack.pop();
// 判断优先级
boolean b = SymbolPriority.judgePriority(pop, s);
// 优先级高 直接入栈
if(b){
// 将栈顶取出的优先放入
symbolStack.push(pop);
symbolStack.push(s);
}else{
// 取出数据栈两个值
String pop1 = numberStack.pop();
String pop2 = numberStack.pop();
int execute = execute(pop, pop2, pop1);
numberStack.push(String.valueOf(execute));
symbolStack.push(s);
}
}
}
}
if(!symbolStack.empty()){
int size = symbolStack.size();
for(int i = 0; i < size; i++){
String pop = numberStack.pop();
String pop1 = numberStack.pop();
String symbol = symbolStack.pop();
int execute = execute(symbol, pop1, pop);
numberStack.push(String.valueOf(execute));
}
}
System.out.println(numberStack.pop());
}
private static int execute(String symbol, String number1, String number2){
int i = Integer.parseInt(number1);
int i1 = Integer.parseInt(number2);
switch (symbol){
case "+":
return i + i1;
case "-":
return i - i1;
case "*":
return i * i1;
case "/":
return i / i1;
default:
break;
}
return 0;
}
}