zoukankan      html  css  js  c++  java
  • 使用栈完成算术表达式的计算

    前言:本篇文章讲解如何利用栈,完成一个简单的算术表达式的计算过程。为了简单起见,首先假设操作数是整数,而运算符为四种类型:+、-、*、/

      1. 基本思路:为了完成算术表达式的计算,用到了两个栈,一个用于存放操作数,另一个用于存放操作符。
        1. 假设:程序中定义了两个栈:operandStack(用来存放操作数)、operatorStack(用于存放操作符)。
        2. 在处理操作数和操作符之前,首先将它们压入栈中。当要处理一个操作符时,从operatorStack中将它弹出,然后将它应用在来自operandStack的前两个操作数上,得到的结果再压入operandStack中。
      2. 实现的详细步骤:
        1. 扫描阶段:程序从左到右扫描表达式,提取操作数、运算符和括号。
          1. 如果提取的字符是一个操作数,将它压入operandStack中。
          2. 如果提取的字符是一个+或-的运算符,因为+、-运算符在算术表达式中的优先级是最低的,所以此时在将+或者-运算符插入栈中之前,可以处理operatorStack栈顶的所有运算符,最后将提取出来的运算符压入operatorStack中。
          3. 如果提取的字符是一个*或/的运算符,则处理operatorStack栈顶的所有*和/的运算符,最后将新提取出来的运算符压入operatorStack中。
          4. 如果提取出来的运算符是一个"(",则将它压入operatorStack中。
          5. 如果提取出来的运算符是一个")",则重复处理operatorStack栈顶的运算符,直到看到栈顶的运算符为")"。
        2. 清除栈阶段:重复处理来自operatorStack栈顶的运算符,直到operatorStack为空为止。
      3. 代码实现:
    • public static int evaluateExpression(String expression){
    •         Stack<Integer> operandStack = new Stack<Integer>();        //存放操作数的栈
    •         Stack<Character> operatorStack = new Stack<Character>();//存放运算符的栈
    •         
    •         String[] charArr = expression.split("");        //将字符串分割成单个字符
    •         for(int i = 0; i < charArr.length; i++){
    •             if(charArr[i].trim().equals("")){        //如果字符串为空,则跳过此次循环
    •                 continue;
    •             }else if(charArr[i].trim().equals("+") || charArr[i].trim().equals("-")){
    •                 //如果字符串为"+"或者"-",则执行栈中已存数据的加减乘除计算
    •                 while(!operatorStack.isEmpty() &&
    •                         (operatorStack.peek() == '+' ||
    •                         operatorStack.peek() == '-' ||
    •                         operatorStack.peek() == '*' ||
    •                         operatorStack.peek() == '/')){
    •                     processOneOperator(operandStack,operatorStack);
    •                 }
    •                 operatorStack.push(charArr[i].charAt(0));//将操作符压入操作符栈中
    •             }else if(charArr[i].trim().equals("*") || charArr[i].trim().equals("/")){
    •                 //如果字符串为"*"或者"/",则执行栈中已存数据的乘除计算
    •                 while(!operatorStack.isEmpty() &&
    •                         (operatorStack.peek() == '*' ||
    •                         operatorStack.peek() == '/')){
    •                     processOneOperator(operandStack, operatorStack);
    •                 }
    •                 operatorStack.push(charArr[i].charAt(0));
    •             }else if(charArr[i].trim().equals("(")){
    •                 //如果遇到左括号,则将左括号压入操作符栈中
    •                 operatorStack.push('(');
    •             }else if(charArr[i].trim().equals(")")){
    •                 //如果遇到右括号,则计算栈中的数据,直到遇到左括号为止
    •                 while(operatorStack.peek() != '('){
    •                     processOneOperator(operandStack,operatorStack);
    •                 }
    •                 operatorStack.pop();//将进行过计算的左括号弹出
    •             }else{
    •                 //如果遇到的是操作数,则将操作数直接压入操作数栈中
    •                 operandStack.push(Integer.parseInt(charArr[i]));
    •             }
    •         }
    •         //对栈中数据进行计算,知道栈为空为止
    •         while(!operatorStack.isEmpty()){
    •             processOneOperator(operandStack,operatorStack);
    •         }
    •         //此时操作数栈中的栈顶元素也就是计算结果
    •         return operandStack.pop();
    •     }
    •     
    •     /**
    •      * 对操作符栈顶的一个操作符进行计算
    •      * @param operandStack
    •      * @param operatorStack
    •      */
    •     public static void processOneOperator(Stack<Integer> operandStack,Stack<Character> operatorStack){
    •         char op = operatorStack.pop();     //取操作符的栈顶元素
    •         int op1 = operandStack.pop();    //取操作数的栈顶元素
    •         int op2 = operandStack.pop();    //取操作数的栈顶元素
    •         if(op == '+'){                    //如果操作数为+,则执行两个操作数的求和操作,并将结果压入操作数栈中
    •             operandStack.push(op2 + op1);
    •         }else if(op == '-'){
    •             operandStack.push(op2 - op1);
    •         }else if(op == '*'){
    •             operandStack.push(op2 * op1);
    •         }else if(op == '/'){
    •             operandStack.push(op2 / op1);
    •         }
    •     }

    4.测试代码:

    public static void main(String[] args) {

            // TODO Auto-generated method stub

            System.out.println("7+(1+1)*2 = " + evaluateExpression("7+(1+1)*2"));

        }

    显示结果:

  • 相关阅读:
    各种协议与HTTP协议之间的关系
    在浏览器中输入url地址到显示主页的过程
    TCP 协议如何保证可靠传输
    TCP,UDP 协议的区别
    TCP 三次握手和四次挥手
    OSI与TCP/IP各层的结构与功能,用到的协议
    424. 替换后的最长重复字符
    webstorm快捷键
    S1:动态方法调用:call & apply
    S1:原型继承
  • 原文地址:https://www.cnblogs.com/inghzhang/p/3901334.html
Copyright © 2011-2022 走看看