java用逆波兰表达式实现字符串计算器

1、java版本 

import java.math.BigDecimal;
import java.util.*;

/**
 * @return
 * @author Tmz
 * @description:
 * 后缀表达式(逆波兰)规则:
 *  ①当前符号大于等于优先级大于等于栈顶优先级时弹出符号,并入栈当前符号 ,出栈的符号加入表达式末尾
 *  ②“(” 符号优先级最低
 *  ③ ")" 符号入栈是,符号出栈直到当前为 "(" ,并且该符号也要出栈,出栈的符号加入表达式末尾
 * 计算规则:
 *  遇到数字直接入栈,遇到操作符,则弹出两个项进行运算,将运算结果再入栈,最后栈底元素值则为最终结果
 * @date 2022/6/7 10:11
 */

public  class  HelloWorld {

    public static String[] operator = {"+", "-", "*", "/","%","^","(", ")"};

    public static void main(String[] args) {

        String expression = "-100**2";
        expression=expression.replaceAll("\\s+", ""); //去掉空格
        expression=expression.replace("**", "^"); //支持立方**这种写法
        expression=expression.replace("(-", "(0-"); //解决负数
        System.out.println(expression);
//        System.out.println(getExpressionStack(expression));
        polishNotation(expression);

    }

    public static void polishNotation(String expression) {
        List<String> expressionList = getExpressionStack(expression); //中值表达式栈
        List<String> expressionList2 = new ArrayList<>();
        if ("-".equals(expressionList.get(0))) { //处理开头是负数的情况,直接加上括号
            expressionList2.add("(");
            expressionList2.add("0");
            expressionList2.add(expressionList.get(0));
            expressionList2.add(expressionList.get(1));
            expressionList2.add(")");
            expressionList2.addAll(expressionList.subList(2,expressionList.size()));
        }
        Stack<String> operatorStack = new Stack<>(); //操作符栈
        ArrayList<String> fixStack = new ArrayList<>(); //完整的逆波兰表达式
        Map<String, Integer> operatorLevelMap = new HashMap<>();
        operatorLevelMap.put("(", 0);
        operatorLevelMap.put("+", 1);
        operatorLevelMap.put("-", 1);
        operatorLevelMap.put("*", 2);
        operatorLevelMap.put("/", 2);
        operatorLevelMap.put("%", 2);
        operatorLevelMap.put("^", 3);
        operatorLevelMap.put(")", 4);
        System.out.println(expressionList2);
        String[] operator2 = {"+", "-", "*", "/","%","^"};
        for (String currentElmt : expressionList2) {
            if (Arrays.asList(operator2).contains(currentElmt)) {
                while (!operatorStack.empty() && operatorLevelMap.get(operatorStack.peek()) >= operatorLevelMap.get(currentElmt)) {
                    fixStack.add(operatorStack.pop());
                }
                operatorStack.push(currentElmt);
            }else if("(".equals(currentElmt)){
                operatorStack.push(currentElmt);
            } else if(")".equals(currentElmt)){
                while (!operatorStack.empty() && operatorLevelMap.get(operatorStack.peek()) >= operatorLevelMap.get("(")+1) {
                    fixStack.add(operatorStack.pop());
                }
                if (!operatorStack.empty()) {
                    operatorStack.pop();
                }
            }else{
                fixStack.add(currentElmt);
            }
        }
        while (!operatorStack.isEmpty()) {
            fixStack.add(operatorStack.pop());
        }
        System.out.println(fixStack);

        //计算结果
        Stack<String> calculateStack = new Stack<>();
        for (String fix : fixStack) {
            //操作符号,弹出两个数字计算,并压入结果栈中
            if (Arrays.asList(operator2).contains(fix)) {
                String number2 = calculateStack.pop();
                String number1 = calculateStack.pop();
                switch (fix) {
                    case "+":
                        calculateStack.push(new BigDecimal(number1).add(new BigDecimal(number2)).toString());
                        break;
                    case "-":
                        calculateStack.push(new BigDecimal(number1).subtract(new BigDecimal(number2)).toString());
                        break;
                    case "*":
                        calculateStack.push(new BigDecimal(number1).multiply(new BigDecimal(number2)).toString());
                        break;
                    case "/":
                        calculateStack.push(String.valueOf(Double.valueOf(number1)/Double.valueOf(number2)));
                        break;
                    case "%":
                        calculateStack.push(String.valueOf(Double.valueOf(number1)%Double.valueOf(number2)));
                        break;
                    case "^":
                        calculateStack.push(String.valueOf(Math.pow(Double.valueOf(number1), Double.valueOf(number2))));
                        break;
                }
            }else{
                //数字入栈
                calculateStack.push(fix);
            }
        }
        System.out.println(calculateStack.pop());
    }

    //把表达式转换为 栈
    public static List<String> getExpressionStack(String expression) {
        List<String> retList = new ArrayList<>();
        String fix = "";
        for (int i = 0; i < expression.length(); i++) {
            String tempStr = String.valueOf(expression.charAt(i));
            if (Arrays.asList(operator).contains(tempStr)) {
                if (!"".equals(fix)) {
                    retList.add(fix);
                }
                retList.add(tempStr);
                fix = "";
            }else{
                fix = fix + tempStr;
            }
        }
        if(!"".equals(fix))
            retList.add(fix);
        return retList;
    }

}

2、ahk版本

str:="-2**10"
;msgBox % 1 "+" 2
;msgBox % mod(3,2)
polish_notation(str)
return

;逆波兰表达式https://blog.csdn.net/assiduous_me/article/details/101981332:
polish_notation(expression)
{
    operatorlevel_map:={"(":0,"+":"1","-":1,"*":2,"/":"2","%":2,"^":3,")":4}
    operator_list:={"+":0,"-":0,"*":0,"/":0,"%":0,"^":0}

    ;去除不必要的空格
    expression:=trim(expression)
    expression:=RegExReplace(expression,"\s+","")
    ;替换立方根
    StringReplace expression,expression,**,^,all
    ;替换负数
    StringReplace expression,expression,`(-,`(0-,all
    msgBox % expression
    ;msgBox % expression
    ;①.获取一个中缀表达式集合类似 100+2 -> ["100","+","2"]
    middlefix_list:=[]
    fix:=""
    loop ,parse,expression
    {
        current_value:=A_LoopField
        if(operatorlevel_map.haskey(current_value))
        {
          if(""!=fix)
            middlefix_list.push(fix)
          middlefix_list.push(current_value)
          fix:=""
        }else fix:=fix current_value
    }
    if(fix!="")
      middlefix_list.push(fix)
   if(middlefix_list[1]="-") ;处理开头为负数
   {
       middlefix_list.insertAt(1,"(")
       middlefix_list.insertAt(2,"0")
       middlefix_list.insertAt(5,")")
   }
   ;②.转换为后缀表达式(逆波兰表达式)
    operator_stack:=[]
    suffix_list:=[]
    for  index ,currentElmt in middlefix_list
    {
         if(operator_list.haskey(currentElmt))
         {
             while(operator_stack.length()>0 && operatorlevel_map[operator_stack[operator_stack.Length()]]>=operatorlevel_map[currentElmt])
                suffix_list.push(operator_stack.pop())
             operator_stack.push(currentElmt)
         }else if(currentElmt="(")
            operator_stack.push("(")
         else if(currentElmt=")")
         {
            while(operator_stack.length()>0 && operatorlevel_map[operator_stack[operator_stack.length()]]>operatorlevel_map["("])
               suffix_list.push(operator_stack.pop())
            if(operator_stack.length()>0)
                operator_stack.pop()
         }
         else
            suffix_list.push(currentElmt)
    }
    while(operator_stack.length()>0)
        suffix_list.push(operator_stack.pop())
    ;③.计算表达式最终的值,规则数字入栈,操作符就出栈两个元素计算值并把结果入栈
    number_stack:=[]
    for key,opertor_or_number in suffix_list
    {
       if(operator_list.haskey(opertor_or_number))
       {
            number2:=number_stack.pop()
            number1:=number_stack.pop()
            if(opertor_or_number="+")
                number_stack.push(number1+number2)
            if(opertor_or_number="-")
                number_stack.push(number1-number2)
            if(opertor_or_number="*")
                number_stack.push(number1*number2)
            if(opertor_or_number="/")
                number_stack.push(number1/number2)
            if(opertor_or_number="%")
                number_stack.push(mod(number1,number2))
            if(opertor_or_number="^")
                number_stack.push(number1**number2)
       }else
            number_stack.push(opertor_or_number)
    }
    result:=number_stack.pop()
    msgBox % result

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值