ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

栈的相关应用

2022-01-10 13:01:57  阅读:128  来源: 互联网

标签:numberStack operatorStack token 操作符 应用 相关 expression String


中缀表达式计算器

题目要求:输入一个简单中缀表达式,计算其结果。(以"(10+40/2*3)/2+8")为例) 注意输入只能是简单的四则运算。

算法思路流程:

  1. 第一步:格式化表达式,因为在我们的表达式中会存在两位数或者三位数,当我们进行字符串分割时会导致我们得到表达式与需要计算的表达式不匹配。
private static String insertBlanks(String expression){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/'){
                sb.append(" ");
                sb.append(c);
                sb.append(" ");
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
  • 定义两个栈,一个操作符栈,一个数字栈,遍历格式化后的表达式:
    注意在格式化结束表达式时:需要过滤掉空串;因为在格式化时")"后紧接着又是一个操作符这样在格式化时会插入两个空串,那么在分割时一定会多余产生一个空串:
		System.out.println(expression);
        //格式化表达式
        expression = insertBlanks(expression);
        String[] tokens = expression.split(" ");
        for(String a :tokens){
            System.out.print("\'"+a+"\'");
        }

输出结果如下:
在这里插入图片描述
所以在计算之前我们需要过滤掉空串
3.遍历过滤后的空串:

  • 当遇到数字时,直接进栈
  • 当遇到操作符时
    * 若操作符栈为空直接进栈
    * 若操作符栈,栈顶为"(" 直接进
    * 若操作符栈中为其他操作符时: 如果当前操作符比栈顶的操作符的优先级大时,则进栈;若栈顶的操作符优先级比当前操作符优先级大或相等时,将操作符栈中所有比当前操作符优先级大或相等的进行弹栈计算处理掉,直到遇到"("或者比当前操作符优先级小的为止
  • 当前操作符是")"时将操作符栈中’’(“上面的所有操作符处理掉,最终弹出”("即可。

注意:在进行计算时先弹出数字栈中的元素首先弹出的元素放在操作符右边后弹出的放在左边,并将计算后的结果在进数字栈
整体代码如下:

public class InfixCalculator {
    public static void main(String[] args) {
        String expression = "(10+20/2*3)/2+8";     //结果为28
        try {
            int result = evaluateExpression(expression);
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("Wrong expression");
        }
    }
    private static int evaluateExpression(String expression) {
        System.out.println(expression);
        //定义两个辅助栈
        ArrayStack<Character> operatorStack = new ArrayStack<Character>();
        ArrayStack<Integer> numberStack = new ArrayStack<Integer>();
        //格式化表达式
        expression = insertBlanks(expression);
        String[] tokens = expression.split(" ");  //利用String中的split方法对字符数组进行分割
        for(String a :tokens){
            System.out.print("\'"+a+"\'");
        }
        for (String token :tokens){
            //过滤空串
            if (token.length()==0){
                continue;
                //遍历到+-号
            }else if(token.equals("+") || token.equals('-')){
                while ((!operatorStack.isEmpty()) && (operatorStack.peek() == '+' || operatorStack.peek() == '-' ||
                        operatorStack.peek() == '*' || operatorStack.peek() == '/')){
                    //如果是之前的+-*/ 则进行弹栈并计算
                    processAnOperator(numberStack, operatorStack);
                }
                //如果操作符栈为空 或者 不为空但栈顶为(
                operatorStack.push(token.charAt(0));
                //遍历到 * / 号
            }else if (token.equals("*") || token.equals("/")){
                while (!operatorStack.isEmpty() && (operatorStack.peek() == '*' || operatorStack.peek() == '/')) {
                    //如果之前是别的* / 则需要弹栈 并计算
                    processAnOperator(numberStack,operatorStack);
                }
                //如果操作符栈为空 或者 不为空但栈顶为(
                operatorStack.push(token.charAt(0));

                //遍历到 (
            }else if(token.equals("(")){
                operatorStack.push(token.charAt(0));
                //遍历到 )
            }else if (token.equals(")")){
                while(operatorStack.peek() != '('){
                    //只要操作符栈的栈顶不是做括号   便依次进行弹栈计算
                    processAnOperator(numberStack,operatorStack);
                }
               //最后  弹出左括号
                operatorStack.pop();
            }else{
                //遍历到数字  将其进栈到数字栈中
                numberStack.push(Integer.parseInt(token));
            }
        }
        //处理掉最后的操作符
        while (!operatorStack.isEmpty()){
            processAnOperator(numberStack,operatorStack);
        }
        return numberStack.pop();
    }
    //操作符栈弹栈一个元素 数字栈弹栈两个数字 进行计算 并将新的结果进栈到数字栈
    private static void processAnOperator(ArrayStack<Integer> numberStack, ArrayStack<Character> operatorStack) {
        char op = operatorStack.pop();
        int num1 = numberStack.pop();
        int num2 = numberStack.pop();
        if (op == '+'){
            numberStack.push(num2+num1);
        }else if(op == '-'){
            numberStack.push(num2 - num1);
        }else if(op == '*'){
            numberStack.push(num2 * num1);
        }else if (op == '/'){
            numberStack.push(num2 / num1);
        }
    }

        //对原表达式 进行格式化处理  给所有的非数字字符两边添加空格
        private static String insertBlanks(String expression){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/'){
                sb.append(" ");
                sb.append(c);
                sb.append(" ");
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

标签:numberStack,operatorStack,token,操作符,应用,相关,expression,String
来源: https://blog.csdn.net/zbx479/article/details/122407453

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有