栈的底层(数组)实现和栈实现的综合计算器

//使用栈完成计算一个表达式的结果 10*9-3+5

  • 计算思路: 有两个栈 一个存放数字 一个存放运算符
  • 1、将表达式字符串转换成字符数组 遍历字符数组
  • 2、如果是数字 直接存放到数字栈
  • 3、如果是符号 ;分为两种情况
    (1) 如果符号栈为空 直接将符号入栈
    (2)如果符号栈不为空
    a、当运算符和栈内的运算符进行比较 如果当前的运算符的优先级低于或者等于栈中的运算符,就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算, 将得到的结果push进数栈,然后将当前的符号push符号栈;
    b、如果当前的操作符的优先级大于栈中的运算符 就直接入符号栈
  • 4、当表达式扫描完毕 就顺序从数栈和符号栈pop出相应的数和符号 并运行
  • 5、最后数栈中只有一个数字 即为表达式的结果
public class UseStack {
    
	public static void main(String[] args) {
    	//测试	
		System.out.println(Calculate("10*9-3+5"));
	}
	
	public static int Calculate(String str) { 
		
		ArrayStack2 numStack=new ArrayStack2(10);//数栈
		ArrayStack2 operStack=new ArrayStack2(10);//运算符栈
		int index=0;//遍历字符串所用的下标
		int num1=0;//弹出的第一个数
		int num2=0;//弹出的第二个数
		char oper=0;//弹出的运算符
		int res=0;//弹出的运算符和结果
		char c=0;//从字符串中读取的字符
		char[] expression=str.toCharArray();
		
		String keepnum="";
		//扫描expression
		while(true) {
			c=expression[index];
			//判断 c 是什么 然后进行相应的处理
			if(operStack.isoper(c)) { //c是运算符
				if(!operStack.isEmpty()) { //符号栈不为空  分两种情况
					//当运算符和栈内的运算符进行比较 如果当前的运算符的优先级低于或者等于栈中的运算符,就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算,
				   if(operStack.priority(c)<=operStack.priority((char) operStack.peek())){
					   num1=numStack.pop();
					   num2=numStack.pop();
					   oper=(char) operStack.pop();
					   res=numStack.calculate(num1, num2, oper);
					   numStack.push(res);
					  //操作结束之后 要记得把遍历的操作符存放到符号栈中
					   operStack.push(c);
				   }else {//如果当前的操作符的优先级大于栈中的运算符 就直接入符号栈
					   operStack.push(c);
				   }	
			}else { //符号栈 为空 直接将符号入栈
				operStack.push(c);	
			}
		}
			else {  //如果是数字 直接入数栈
				//numStack.push(c-48);//  "1+3" ---字符1 对应的值是49
				//分析思路 
				//1、当处理多位数时,不能是发现一个数就立即入栈 因为它可能是多位数
				//2、在处理数字时需要向expression的表达式
				//如果数字是expression中的最后一个数 直接入数栈
				keepnum+=c;
				
				if(index==expression.length-1) {
					numStack.push(Integer.parseInt(keepnum));
				} else {
					//如果下一位是运算符 就直接把keepnum  push进入栈内  ;如果不是保留keepnum 继续遍历下一个字符
				if(operStack.isoper(expression[index+1])) {
						numStack.push(Integer.parseInt(keepnum));
						
						//注意!!!每次keepnum用完之后  记得将其恢复为空
						keepnum="";
					}					
				}	
			}
			index++;  
			if(index>=expression.length){  //遍历结束
				break;	
			}
	}

   while(!operStack.isEmpty()) { //当符号栈中的符号全部弹出的时候  计算完全结束  取出数栈中的第一个数即为运算的结果
	   num1=numStack.pop();
	   num2=numStack.pop();
	   oper=(char) operStack.pop(); 
	   res=numStack.calculate(num1, num2, oper);
	   //及得把res存放到numStack中
	   numStack.push(res);
   }
     return res;
	
	}
	
}
//数组模拟栈
class ArrayStack2 {
  
	private int maxsize;
	private int[] array;
	private int top=-1;
	public ArrayStack2(int maxsize) {
		this.maxsize=maxsize;  //这里注意将maxsize传入this.maxsize
		array=new int[this.maxsize];
		
	}
	
	//是否栈满
	public boolean isFull() {
		return top==maxsize-1;
	}
	
	//是否栈空
	public boolean isEmpty() {
		return top==-1;
	}
	
 //入栈操作
	public void push(int value) {
	   //判断是否栈满
		if(top==maxsize-1) {
			System.out.println("栈已满");
		}else {
			top++;
			array[top]=value;
		}
	}
	
	//出栈操作
	public int pop() {
		//判断是否栈空
		if(top==-1) {
			throw new RuntimeException("栈空,没有数据");
		}else {
		int value=array[top];
		top--;
		return value;
		}
	}
	
	//弹出栈顶元素
	public int peek() {
		return array[top];
	}
	
    //遍历栈  从栈顶到栈底部
	public void read() {
		
		if(top!=-1) {
		for(int i=top;i>=0;i--) {
			System.out.println(i+"---"+array[i]);
		}
		}
	}
	
	//返回运算符的优先级 优先级是有程序员设定  优先级用数字表示
	//数字越大优先级越高
   public int priority(char oper) {
	   if(oper=='*'||oper=='/') {
		   return 1;
		   
	   }
	   if(oper=='+'||oper=='-') {
		   return 0;
	   }else {
		   return -1;
	   }
   }
   
   //判断是不是一个运算符
   public boolean isoper(char c) {
	   if(c=='+'||c=='-'||c=='*'||c=='/') {
		   return true;
	   }else 
		   return false;
   }
   
   //计算
   public int calculate(int num1,int num2,char oper) {
	  int res=0;
	  switch(oper) {
	  case '+':
		  res=num1+num2;
		  break;
		  
	  case '-':
		  res=num2-num1;
		  break;
		  
	  case '*':
		  res=num2*num1;
		  break;
	
	  case '/':
		  res=num2 / num1;
		  break;
	 default:
		 break;
	  }
	return res;
   }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值