代码思路✨✨✨✨✨
1,创建两个栈: nums存放表达式中的数字,oper存放表达式中的运算符
2,对表达式字符串进行遍历扫描:
(1)为数字 入栈nums
(2)为运算符:oper空,直接入栈;oper不为空但是当前运算符的优先级大于oper.top(),入栈oper;当前运算符优先级小于等于oper.top()----从nums中pop出两个数字,从oper中pop出一个运算符,进行运算并将运算结果入栈nums,持续对当前运算符优先级和oper.top()进行比较,并且重复以上操作,直到符合入栈的条件,最后将当前运算符入栈oper
3,依次将nums和oper中的数字弹出,进行运算,并且将运算结果入栈nums
4,nums.top() 就是表达式的结果
代码的核心思路是:除了当前运算符为 * / 而前一个运算符为 + - 这样的情况当前运算符可以入栈,其他情况均先计算oper.top()运算符对应的运算,再对当前运算符入栈即: 确保了先乘除后加减的运算规则
package DataStructure;
import java.util.Stack;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 86178
* Date: 2024-02-14
* Time: 13:38
*/
public class Calculator {
public static void main(String[] args) {
Stack<Integer> nums1=new Stack();
nums1.push((int)'a');
MyStack2 nums=new MyStack2(10);
MyStack2 oper=new MyStack2(10);
int n1=0;
int n2=0;
int op=0;
int res=0;
//todo 用于拼接多位数
String keepNum="";
String s="70+10/5-20/4+12";
//System.out.println(s.length());
for(int i=0;i<s.length();i++){
char c=s.charAt(i);
if(!oper.isOper(c)){
//nums.Push(c-48);//数字直接入栈
//todo 处理多位数
keepNum+=c;
//todo 判断下一个字符是不是数字 是则继续扫描
if(i==s.length()-1){
nums.Push(Integer.parseInt(keepNum));
}else{
if(oper.isOper(s.charAt(i+1))){
//如果下一位是运算符
nums.Push(Integer.parseInt(keepNum));
keepNum="";
}
}
} else{
if(oper.isEmpty()){
oper.Push(c);
}else{
if(oper.priority(c)> oper.priority(oper.Top())){
oper.Push(c);
}else {
//todo 此处应该持续判断优先级
// 例如 - / + 如果只判断一次 则栈中的- + 则不符合 先计算优先级大于等于自己的原则
while(!oper.isEmpty() && oper.priority(c)<= oper.priority(oper.Top())) {
n1 = nums.Pop();
n2 = nums.Pop();
op = oper.Pop();
res = nums.cal(n1, n2, op);
nums.Push(res);
}
oper.Push(c);
}
}
}
}
while(!oper.isEmpty()){
n1= nums.Top();
nums.Pop();
n2=nums.Top();
nums.Pop();
op= oper.Top();
oper.Pop();
res=nums.cal(n1,n2,op);
nums.Push(res);
}
System.out.println(nums.Top());
}
}
//todo 先创建一个栈
class MyStack2{
private int top;//栈顶
private int[] StArr;//数组
private int maxSize;//栈的大小
public MyStack2(int max){
maxSize=max;
StArr=new int[max];
top=-1;
}
public boolean isEmpty(){
return top==-1;//当top=-1 为空
}
public boolean isFull(){
return top==maxSize-1;
}
//todo 入栈
public void Push(int n){
if(isFull()){
System.out.println("栈满");
return;
}else {
StArr[++top]=n;
}
}
//todo 出栈
public int Pop(){
if(isEmpty()) throw new RuntimeException("栈空");
else{
int ret=StArr[top];
top--;
return ret;
}
}
//todo 返回栈顶元素
public int Top(){
if(isEmpty()) throw new RuntimeException("栈空");
else{
return StArr[top];
}
}
//todo 打印栈的信息
public void show(){
if(isEmpty()){
System.out.println("栈空");
return;
}
System.out.println("-----------------------");
System.out.println("top="+top);
System.out.println("打印栈");
for(int i=top;i>=0;i--){
System.out.print(StArr[i]+" ");
}
System.out.println();
System.out.println("-----------------------");
}
//todo 判断运算符号的优先级
//在Java中 int 和 char可以进行转换 ASCII
public int priority(int oper){
if(oper=='+' || oper=='-'){
return 0;
}else if(oper=='*' || oper=='/'){
return 2;
}else{
return -1;//假定只有+ - * /
}
}
public boolean isOper(char c){
return c=='+' || c=='-' || c=='*' || c=='/';
}
//todo 计算方法
public int cal(int n1,int n2,int oper){
int res=0;//计算结果
switch (oper){
case '+':
res=n1+n2;
break;
case '-':
res=n2-n1;
break;
case '*':
res=n1*n2;
break;
case '/':
res=n2/n1;
break;
}
return res;
}
}