1.运算规则
数字和符号都进栈
遇到乘除不变 遇到加减比较栈顶元素的优先级
2.栈的特点
先进后出、只允许两端数据操作
最先放入栈中元素在栈底,最后放入的元素在栈顶,
而删除元素刚好相反,最后放入的元素最先删除,最先放入的元素最后删除
栈的数组设计思路
\
对应代码
import java.util.Scanner;
public class ArrayStackDemo {
public static void main(String[] args) {
ArrayStrack strack = new ArrayStrack(4);
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":
strack.list();
break;
case "exit":
scanner.close();
loop=false;
System.out.println("退出");
break;
case "push":
System.out.println("输入一个数");
int value=scanner.nextInt();
strack.push(value);
break;
case "pop":
try {
int r=strack.pop();
System.out.println("出栈的数据是"+r);
}catch (Exception e){
System.out.println(e.getMessage());
}
break;
default:
break;
}
}
System.out.println("程序退出");
}
}
class ArrayStrack{
private int maxSize;
private int[] stack;
private int top=-1;
public ArrayStrack(int maxSize) {
this.maxSize = maxSize;
stack= new int[maxSize];
}
public boolean isFull(){
if (top==maxSize-1){
return true;
}
return false;
}
public boolean isEmpty(){
if (top==-1){
return true;
}
return false;
}
public void push(int value){
if (isFull()){
System.out.println("栈满了");
}
top++;
stack[top]=value;
}
public int pop(){
if (isEmpty()){
//抛出异常
throw new RuntimeException("栈空,没有数据");
}
int value=stack[top];
top--;
return value;
}
public void list(){
if (isEmpty()){
System.out.println("栈空没有数据了");
return;
}
for (int i=top;i>=0;i--){
System.out.println("stack["+i+"]="+stack[i]);
}
}
}
3.思路解析:
例子:10-4*4/4
public static void main(String[] args) {
String expression = "10-4*4/4";
// 创建两个栈,一个数栈,一个符号栈
ArrayStack2 numStack = new ArrayStack2(10);
ArrayStack2 operStack = new ArrayStack2(10);
int index = 0;
int num1 = 0;
int num2 = 0;
int oper = 0;
int res = 0;
char ch = ' ';
String keepNum = "";
while (true){
//每次返回一个字符串,一次返回一个字符。注意不能直接使用charAt(0)因为不能遍历
//也不能直接使用substring(index,index+1),因为格式不同一个是字符串一个是字符。
ch=expression.substring(index,index+1).charAt(0);
if(operStack.isOper(ch)){
if (!operStack.isEmpty()) {
//使用priority判断优先级,如果<=那就弹出2个num栈,弹出1个oper栈。
//然后res接受计算的结果,最后将计算结果压进数字栈。
if (operStack.priority(ch) <= operStack.priority(operStack.peek())) {
//num1接受第一个弹出,num2接受第二个弹出
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res);
//还要把当前的符号入符号栈,因为在这个符号优先级低还没使用呢。
operStack.push(ch);
}
//如果优先级大于栈中的符号就直接压栈。
else {
operStack.push(ch);
}
}
//如果栈为空也是直接压栈。
else {
operStack.push(ch);
}
}
//如果不是符号那肯定是数字所以压数栈。
else{
// 循环添加多位数字,防止多位数的情况
keepNum +=ch;
/*
先判断后一位是不是运算符,从index+1开始,因为经过前面的判断后,ch第1位肯定是
数字才能到这一轮
else语句,如果是符号就已经从前面的operStack.push(ch)压栈了。
*/
if(index == expression.length() -1) {
numStack.push(Integer.parseInt(keepNum));
} else {
if (operStack.isOper(expression.substring(index + 1, index + 2).charAt(0))) {
//把keepNun转换成数字进行压栈。
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
// 清空(注意!!!)
}
}
//循环遍历
index++;
if(index >= expression.length()) {
break;
}
}
// 当表达式扫描计算完毕,就顺序的从 数栈和符号栈中pop出相应的数和符号,并运行
while(true) {
// 如果符号栈为空,则计算到最后的结果, 数栈中只有一个数字【结果】
if(operStack.isEmpty()) {
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = numStack.cal(num1, num2, oper);
numStack.push(res);//入栈
}
// 将数栈的最后数,pop出,就是结果
int result = numStack.pop();
System.out.printf("表达式 %s = %d", expression, result);
}