
ArrayStack
public class ArrayStack {
private int maxSize;// 最大的尺寸
private int[] stack;// 使用数组模拟
private int top = -1;// 栈指针 , 初始为-1
public ArrayStack(int maxSize) {// 初始化
this.maxSize = maxSize;
stack = new int[this.maxSize];
}
// 判断是否为空
public boolean isEmpty(){
return top == -1;
}
// 判断是否为满
public boolean isFull(){
return top == maxSize - 1;
}
// 查看栈顶元素
public int peek(){
return stack[top];
}
// 进栈
public void push(int value){
// 判断满栈
if(isFull()){
System.out.println("栈满~~");
return;
}
top++;
stack[top] = value;
}
// 出栈 -- 从栈顶出栈
public int pop(){
if(top == -1){
throw new RuntimeException("栈空~~");
}
int value = stack[top];
top--;
return value;
}
// 遍历栈 == 从栈顶开始遍历
public void stackList(){
if(isEmpty()){
throw new RuntimeException("栈空~~");
}
for (int i = 0; i < maxSize ; i++) {
System.out.printf("stack[%d]=%d\n",i,stack[i]);
}
}
// 制定优先级
public int priority(int oper){
if(oper == '*' || oper == '/'){
return 1;// 优先级高
}else if(oper == '+' || oper == '/'){
return 0;// 优先级低
}else{
return -1;// 有问题,只限于+ - * /
}
}
// 判断是符号还是数字
public boolean isNum(char val){
// 如果为= - * / 中的一个,那么就不是数字,否则就是数字
return val == '+' || val == '-' || val == '*' || val == '/';
}
// 计算
public int cal(int num1 , int num2 ,int op){
int res = 0;// 返回的计算结果
switch (op){
case '+':
res = num1 +num2;
break;
case '-':
res = num2 - num1;
break;
case '*':
res = num1*num2;
break;
case '/':
res = num2 / num1;
break;
default:
break;
}
return res;
}
}
Calculator
public class Calculator {
public static void main(String[] args) {
// 定义一个表达式
String expression = "70+3*2-1";
// 定义两个栈
ArrayStack numStack = new ArrayStack(10);
ArrayStack operStack = new ArrayStack(10);
// 定义其他的变量
int index = 0;// 指针索引
int oper = 0;// 符号
int num1 = 0;
int num2 = 0;
int res = 0;// 结果
char ch = ' '; // 每次扫描到的char保存在ch中
String keepNUm = "";//用于拼接多位数
//遍历整个表达式
while(true){
ch = expression.substring(index,index+1).charAt(0);// 将截取的字符串转化为字符
if(operStack.isNum(ch)){// 如果是运算符
// 判断operStack是否为空
if(!operStack.isEmpty()){// 不为空
// 判断当前的这个运算符和栈顶的运算符的优先级
// 如果当前的运算符的优先级小于等于栈顶的运算符的优先级,则拿出来运算
if(operStack.priority(ch) <= operStack.priority(operStack.peek())){
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = operStack.cal(num1, num2, oper);
// 将计算结果压栈
numStack.push(res);
// 将当前的运算符压栈
operStack.push(ch);
}else{// 大于的话直接入栈
operStack.push(ch);
}
}else{// 为空
operStack.push(ch);
}
}else{// 如果是数字,直接压栈
//numStack.push(ch - 48);// 因为在ASCII的表中 1 - > 49 3 - > 51 正好相差48
// 必须考虑index的指向是否是多位数,比如10
// 如果是多位数的话,就必须将要都扫描到,就需要在压栈之前去判断下一位是否为数字还是操作符
// 首先先判断是否是最后一位
keepNUm += ch;
if(index == expression.length()-1){
numStack.push(Integer.parseInt(keepNUm));
}else{
if(operStack.isNum(expression.substring(index+1,index+2).charAt(0))){//是操作符,直接压栈
numStack.push(Integer.parseInt(keepNUm));
keepNUm = "";// 清空为下一次的拼接做好准备
}
}
}
index++;// 辅助指针后移一位
// 判断是否到了最后一位
if(index >= expression.length()){
break;
}
}
// 计算栈中的数字
while(true){
// 判断栈中是否还有运算符
if(operStack.isEmpty()){
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = operStack.cal(num1,num2,oper);
numStack.push(res);
}
System.out.printf("表达式:%s=%d",expression,res);
}
}