实现思路:
package com.atguigu.stack;
public class ArrayStackDemo {
public static void main(String[] args) {
ArrayStack arrayStack = new ArrayStack(4);
boolean empty = arrayStack.isEmpty();
System.out.println("isEmpty?"+empty);
arrayStack.push(3);
arrayStack.push(6);
arrayStack.push(2);
arrayStack.push(7);
boolean full = arrayStack.isFull();
System.out.println("isFull?" + full);
arrayStack.show();
while (!arrayStack.isEmpty()) {
System.out.println(arrayStack.pop());
}
arrayStack.show();
}
}
/**
* 定义一个类表示栈
*/
class ArrayStack{
private int maxSize;
private int[] stack;
private int top = -1;
/**
* 展示整个栈
*/
public void show() {
if (isEmpty()) {
System.out.println("当前栈空,无法显示");
return;
}
for (int i = top; i >= 0; i--) {
System.out.printf("stack[%d] = %d", i, stack[i]);
System.out.println();
}
}
/**
* 出栈
* @return
*/
public int pop() {
if (isEmpty()) {
System.out.println("当前栈空,出栈失败");
throw new RuntimeException("当前栈空,出栈失败");
}
int data = stack[top];
top--;
return data;
}
/**
* 数据入栈
* @param data
*/
public void push(int data) {
if (isFull()) {
System.out.println("当前栈满,入栈失败");
return;
}
top++;
stack[top] = data;
}
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty() {
return top == -1;
}
/**
* 判断栈是否满
* @return
*/
public boolean isFull() {
return top == maxSize - 1;
}
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
}
}
package com.atguigu.stack;
public class LinkedListStackDemo {
public static void main(String[] args) {
LinkedListStack linkedListStack = new LinkedListStack();
boolean empty1 = linkedListStack.isEmpty();
System.out.println(empty1);
Node node = new Node(1);
Node node1 = new Node(6);
Node node2 = new Node(3);
Node node3 = new Node(8);
linkedListStack.push(node);
linkedListStack.push(node1);
linkedListStack.push(node2);
linkedListStack.push(node3);
linkedListStack.show();
boolean empty = linkedListStack.isEmpty();
System.out.println(empty);
}
}
class LinkedListStack {
private Node top = null;
/**
* 遍历展示栈内容
*/
public void show() {
if (isEmpty()) {
System.out.println("当前栈空,无数据展示");
}
Node help = top;
while (help != null) {
System.out.println(help.getData());
help = help.getPre();
}
}
/**
* 弹出数据
* @return
*/
public Node pop() {
if (isEmpty()) {
System.out.println("当前栈空,无法弹出");
return null;
}
Node node = top;
top = node.getPre();
top.setNext(null);
return node;
}
/**
* 压入数据
* @param node
*/
public void push(Node node) {
if (top == null) {
top = node;
return;
}
top.setNext(node);
node.setPre(top);
top = top.getNext();
}
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty() {
return top == null;
}
}
class Node{
private int data;
private Node next;
private Node pre;
@Override
public String toString() {
return "Node{" +
"data=" + data +
'}';
}
public Node getPre() {
return pre;
}
public void setPre(Node pre) {
this.pre = pre;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public Node(int data) {
this.data = data;
}
}
实现思路:
package com.atguigu.stack;
import java.nio.file.Paths;
public class Calculator {
public static void main(String[] args) {
String expression = "3+2*6-2";
//创建两个栈
ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operStack = new ArrayStack2(10);
char ch = ' ';
for (int i = 0; i < expression.length(); i++) {
ch = expression.substring(i, i + 1).charAt(0);
if (operStack.isOper(ch)) {
//是运算符,先判断符号栈是否为空,为空直接入栈
if (operStack.isEmpty()) {
operStack.push(ch);
continue;
}
//符号栈不为空,判断一下优先级
//先出栈一个运算符,和当前的字符优先级进行比较
//如果当前优先级大于出栈的运算符,当前优先级直接入栈
//如果当前优先级小于等于出栈的运算符,就先计算,再将当前优先级入栈
//这里面,我直接出栈了一个符号,可以增加一个方法,返回当前栈顶的数据,
// 但不是出栈,只是看一眼
// int pop = operStack.pop();
if (operStack.priority(operStack.peek()) < operStack.priority(ch)) {
// operStack.push(pop);
operStack.push(ch);
}else{
//从数栈出栈两个数
int num1 = numStack.pop();
int num2 = numStack.pop();
int pop = operStack.pop();
//计算
int cal = numStack.cal(num1, num2, (char) pop);
//将结果入数栈,将当前的运算符入符号栈
numStack.push(cal);
operStack.push(ch);
}
}else {
//是数字,入数栈
//这里,记得转换为int值,否则入栈的是字符串对应的ASCLL值
numStack.push(Integer.parseInt(expression.substring(i, i + 1)));
}
}
//将两个栈打印看看
numStack.show();
System.out.println("----------");
//符号栈显示可能会有些奇怪,因为显示的是符号对应的ASCLL码值
operStack.show();
//运算符处理完毕,开始计算栈中的数据
while (!operStack.isEmpty()) {
//数栈出两个,符号栈出一个
int num1 = numStack.pop();
int num2 = numStack.pop();
int pop = operStack.pop();
//计算
int cal = numStack.cal(num1, num2, (char) pop);
numStack.push(cal);
}
//运算结束,数栈中有一个元素,就是运算符结果
int result = numStack.pop();
System.out.println(expression + "=" + result);
}
}
/**
* 定义一个类表示栈
*/
class ArrayStack2 {
private int maxSize;
private int[] stack;
private int top = -1;
/**
* 偷偷看一眼栈顶,不是出栈
* @return
*/
public int peek() {
return stack[top];
}
/**
* 计算
* @param num1
* @param num2
* @param oper
* @return
*/
public int cal(int num1, int num2, char oper) {
int res = 0;
switch (oper) {
case '+':
res = num2 + num1;
break;
case '-':
res = num2 - num1;
break;
case '*':
res = num2 * num1;
break;
case '/':
res = num2 / num1;
break;
default:
break;
}
return res;
}
/**
* 判断是否是运算符
* @param val
* @return
*/
public boolean isOper(char val) {
return val == '+' || val == '-' || val == '*' || val == '/';
}
/**
* 返回运算符的优先级,优先级越高,数字越大
* @param oper
* @return
*/
public int priority(int oper) {
if (oper == '*' || oper == '/') {
return 1;
} else if (oper == '+' || oper == '-') {
return 0;
}else {
//暂时不考虑括号等运算符
return -1;
}
}
/**
* 展示整个栈
*/
public void show() {
if (isEmpty()) {
System.out.println("当前栈空,无法显示");
return;
}
for (int i = top; i >= 0; i--) {
System.out.printf("stack[%d] = %d", i, stack[i]);
System.out.println();
}
}
/**
* 出栈
* @return
*/
public int pop() {
if (isEmpty()) {
System.out.println("当前栈空,出栈失败");
throw new RuntimeException("当前栈空,出栈失败");
}
int data = stack[top];
top--;
return data;
}
/**
* 数据入栈
* @param data
*/
public void push(int data) {
if (isFull()) {
System.out.println("当前栈满,入栈失败");
return;
}
top++;
stack[top] = data;
}
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty() {
return top == -1;
}
/**
* 判断栈是否满
* @return
*/
public boolean isFull() {
return top == maxSize - 1;
}
public ArrayStack2(int maxSize) {
this.maxSize = maxSize;
stack = new int[maxSize];
}
}
从右至左扫描表达式,遇到数字是,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对他们做相应的运算,并将结果入栈;直到表达式左端
从左至右扫描,遇到数字时,将数字压入栈,遇到运算符时,弹出栈顶的两个数,运算符对他们做相应的计算,并将结果入栈。重复该操作,直到最右端。
要求:
package com.atguigu.stack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
public class PolandNotation {
public static void main(String[] args) {
//先定义一个逆波兰表达式
//(3+4) * 5 - 6
//为了简化操作,逆波兰表达式中的数字和符号使用空格隔开
String suffixExpression = "3 4 + 5 * 6 -";
//1.先将 suffixExpression 放到 ArrayList中
//2.将ArrayList传给一个方法,配合栈完成计算
List<String> listString = getListString(suffixExpression);
int calculate = calculate(listString);
System.out.println(calculate);
}
public static List<String> getListString(String suffixExpression) {
//分隔字符串
String[] split = suffixExpression.split(" ");
ArrayList<String> strings = new ArrayList<>(Arrays.asList(split));
return strings;
}
public static int calculate(List<String> list) {
Stack<Integer> numStack = new Stack<>();
int num1;
int num2;
for (String str : list) {
if (str.matches("\\d+")) {
numStack.push(Integer.parseInt(str));
} else {
num1 = numStack.pop();
num2 = numStack.pop();
int result = 0;
switch (str.charAt(0)) {
case '+':
result = num2 + num1;
break;
case '-':
result = num2 - num1;
break;
case '*':
result = num2 * num1;
break;
case '/':
result = num2 / num1;
break;
default:
break;
}
numStack.push(result);
}
}
return numStack.pop();
}
}
步骤:
package com.atguigu.stack;
import java.util.*;
public class PolandNotation {
public static void main(String[] args) {
//中缀表达式转后缀表达式
String expression = "1+((2+3)*4)-5";
List<String> strings = toInfixExpressionList(expression);
System.out.println(strings);
List<String> strings1 = parseSuffixExpressionList(strings);
System.out.println(strings1);
int calculate1 = calculate(strings1);
System.out.println(expression + "=" + calculate1);
//先定义一个逆波兰表达式
//(3+4) * 5 - 6
//为了简化操作,逆波兰表达式中的数字和符号使用空格隔开
String suffixExpression = "3 4 + 5 * 6 -";
//1.先将 suffixExpression 放到 ArrayList中
//2.将ArrayList传给一个方法,配合栈完成计算
List<String> listString = getListString(suffixExpression);
int calculate = calculate(listString);
System.out.println(calculate);
}
/**
* 将中缀表达式转换为后缀表达式
* @param list
* @return
*/
public static List<String> parseSuffixExpressionList(List<String> list) {
Stack<String> s1 = new Stack<>();
//数字栈在转换过程中没有pop操作,并且后面要逆序输出,因此直接使用ArrayList即可
ArrayList<String> resultList = new ArrayList<>();
for (String item : list) {
//如果是数字,加入链表
if (item.matches("\\d+")) {
resultList.add(item);
} else if (item.equals("(")) {
s1.push(item);
} else if (item.equals(")")) {
//如果是右括号,依次弹出s1中的符号,直到遇到一个左括号,弹出的符号加入list中
while (!s1.peek().equals("(")) {
resultList.add(s1.pop());
}
s1.pop();
}else {
//判断item和栈顶的优先级
//当item的优先级,小于等于s1栈顶的优先级,将s1栈顶的运算符弹出加入list中
while (!s1.isEmpty() && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {
resultList.add(s1.pop());
}
//将item压入s1
s1.push(item);
}
}
//将s1中剩下的元素加入到list中
while (!s1.isEmpty()) {
resultList.add(s1.pop());
}
return resultList;
}
/**
* 中缀表达式扫描,获取一个list
* @param s
* @return
*/
public static List<String> toInfixExpressionList(String s) {
ArrayList<String> list = new ArrayList<>();
StringBuilder sb = new StringBuilder();
char c;
for (int index = 0; index < s.length(); index++) {
c = s.charAt(index);
//判断c是否是一个数字
if (c < 48 || c > 57) {
//不是一个数字
list.add(c + "");
}else{
//是一个数字,考虑多位数的问题
sb.delete(0, sb.length());
while (index < s.length() && (c = s.charAt(index)) >= 48 && (c = s.charAt(index)) <= 57) {
sb.append(c);
index++;
}
index--;
list.add(sb.toString());
}
}
return list;
}
/**
* 字符串转list
* @param suffixExpression
* @return
*/
public static List<String> getListString(String suffixExpression) {
//分隔字符串
String[] split = suffixExpression.split(" ");
ArrayList<String> strings = new ArrayList<>(Arrays.asList(split));
return strings;
}
/**
* 计算中缀表达式的值
* @param list
* @return
*/
public static int calculate(List<String> list) {
Stack<Integer> numStack = new Stack<>();
int num1;
int num2;
for (String str : list) {
if (str.matches("\\d+")) {
numStack.push(Integer.parseInt(str));
} else {
num1 = numStack.pop();
num2 = numStack.pop();
int result = 0;
switch (str.charAt(0)) {
case '+':
result = num2 + num1;
break;
case '-':
result = num2 - num1;
break;
case '*':
result = num2 * num1;
break;
case '/':
result = num2 / num1;
break;
default:
break;
}
numStack.push(result);
}
}
return numStack.pop();
}
}
/**
* 定义一个类,返回运算符对应的优先级
*/
class Operation {
private static int ADD = 1;
private static int SUB = 1;
private static int MUL = 2;
private static int DIV = 2;
public static int getValue(String operation) {
int result = 0;
switch (operation) {
case "+":
result = ADD;
break;
case "-":
result = SUB;
break;
case "*":
result = MUL;
break;
case "/":
result = DIV;
break;
default:
break;
}
return result;
}
}