用栈模拟表达式单位运算


/**
 * 使用栈模拟表达式单位运算的计算思路:
 * 1.通过一个index值来遍历我们的表达式
 * 2.如果我们发现是一个数字,就直接入数栈
 * 3.如果发现扫描的是一个符号
 *   3.1如果发现当前的符号栈为空,就直接入栈
 *   3.2如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或等于栈中的操作符,就需要从数栈中pop出两个数
 *     从符号栈中pop出一个符号,进行运算,将得到的结果入数栈,然后将当前的操作符入符号栈
 *     如果当前的操作符的优先级大于栈中的操纵符,就直接入符号栈
 *4.当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的数和符号,并运行
 *5.最后在数栈只有一个数字,就是表达式的结果。   
 * 
 * @author Rocco_L
 *
 */

public class Calcualtor {
 public static void main(String[] args) {
  String expression = " 7+2*6-2";
  //创建两个栈,数栈和符号栈
  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 = ' ';  //将每次扫描得到的char保存到ch
  //开始while循环的扫描expression
  while(true){
   //依次得到expression 的每一个字符
   ch = expression.substring(index, index+1).charAt(0);
   //判断ch是什么,然后做相应的处理
   if(operStack.isOper(ch)){ //如果是运算符
    //判断符号栈是否为空
    if(!operStack.isEmpty()){
     //如果符号栈有操作符,就进行比较,
     //如果当前的操作符的优先级小于或者等于栈中的操作符,就需要从数栈中pop出两个数
     //从符号栈中pop出一个符号,进行运算,将得到结果,入数栈,然后当前的操作符入符号栈
     if(operStack.prioriyt(ch)<= operStack.prioriyt(operStack.peek())){
      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); //1,2,3
    }
   }else{
    //如果是数,则直接入数栈
    numStack.push(ch-48);  // ? "1+3" '1' 
   }
   //让index+1 并判断是否扫描到expression最后
   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);
  }
  System.out.printf("表达式%s = %d",expression,numStack.pop());
  
 }

}

//定义一个表示栈
class ArrayStack2{
 private int maxSize; //栈的大小
 private int [] stack ; //数据放在数组中
 private int top = -1; //top表示栈顶,初始化为-1
 
 public ArrayStack2(int maxSize) {
  this.maxSize = maxSize;
  stack = new int[this.maxSize];
 }
 
 //可以返回当前栈顶的值,但不是真正的pop
 public int peek(){
  return stack[top];
 }
 
 //栈满
 public boolean isFull(){
  return top== maxSize -1;
 }
 
 public boolean isEmpty(){
  return top == -1;
 }
 //入栈 - push
 public void push(int value){
  //判断栈满
  if(isFull()){
   System.out.println("栈满");
   return;
  }
  top++;
  stack[top] =value;
 }
 
 //出栈 - pop   返回栈顶的数据
  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.printf("stack[%d] = %d \n", i , stack[i]);
   }
  }

//返回运算符的优先级, 优先级是程序员来确定的,优先级使用数字表示
 //数字越大,则优先级越高
 public int prioriyt (int oper){
  if(oper == '*' || oper == '/'){
   return 1;
  }else if (oper == '+' || oper == '/'){
   return 0;
  }else{
   return -1; //假定目前的表达式只有+,-,*,/
  }
 }

//判断是不是一个运算符
 public boolean isOper(char val){
  return val == '+'  ||  val =='-'  || val == '*'  ||  val =='/'; 
 }

//计算方法
 public int cal(int num1, int num2 , int 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、付费专栏及课程。

余额充值