中缀表达式转后缀表达式(java)

介绍

一般我们见到的算术表达式都是中缀表达式。
如:1 + 2 * (4 - 2) - 3
此时我们的运算思路就是先计算括号中的数,然后计算乘数,最后计算加减。算数运算规则:
1:运算符优先级高的先运算。
2:先括号内,后括号外。
3:同级别先左后右。

但是显然对于计算机来说不太方便计算和判断。因此为把它转换为后缀表达式来计算。
后缀表达式:1242-*+3-
运算符的优先级:

操作符优先级
+ -1
* /2
^3
! l o g s c t4
操作符含义
阶乘的运算
l对数ln的运算
o对数log2的运算
g开根号的运算
s三角函数sin的运算
c三角函数cos的运算
t三角函数tan的运算

思路:
1.遇到数字就加入到后缀表达式链表中。
2.遇到左括号’('就直接入栈。
3.遇到操作符优先级比栈顶操作符优先级低的话,就把栈中优先级大于等于它的依次输出,直到遇到
(1.优先级比它小的
(2.或者是左括号时
(3.或者栈为空时
这三种情况停止出栈,出栈的操作符全部依次加入到后缀表达式链表中。并且把此时的操作符入栈。
4.遇到右括号时,操作符一直出栈,出栈的操作符全部依次加入到后缀表达式链表中。直到遇到左括号是停止,且右括号不入栈。
6.当循环完毕时把栈中的操作符全部出栈,加入后缀表达式链表中。

过程:

步骤中缀表达式堆栈后缀表达式
11+2*(4-2)-3
2+2*(4-2)-31
32*(4-2)-3+1
4*(4-2)-3+12
5(4-2)-3+*12
64-2)-3+*(12
7-2)-3+*(124
82)-3+*(-124
9)-3+*(-1242
10)-3+*(1242-
11)-3+*1242-
12-3+*1242-
13-3+1242-*
15-31242-*+
163-1242-*+
17-1242-*+3
181242-*+3-

此时的运算过程为:
遇到数字入栈,遇到操作符出栈运算,并把计算得到的值入栈。

步骤后缀表达式栈堆运算
11242-*+3-
2242-*+3-1
342-*+3-12
42-*+3-124
5-*+3-1242
6*+3-124-2=2
7*+3-122
8+3-12*2=4
9+3-14
103-1+4=5
113-5
12-53
135-3=2
142

所以最后得到的值为2。我上面定义的其它操作符也可以用。这里就不举例子了。
我用这个方法写过一个带界面的科学计算器。有兴趣的话可以看看。链接如下:
java实现科学计算器

方法实现的代码如下:

private List<String> zhongZhui(String str) {//把输入的字符串转换成中缀表达式。存入list中
        int index = 0;
        List<String> list = new ArrayList<>();
        do{
            char ch = str.charAt(index);
            if("+-*/^!logsct()".indexOf(str.charAt(index)) >= 0){
                //是操作符,直接添加至list中
                index ++;
                list.add(ch+"");
            }else if (str.charAt(index) == 'e' || str.charAt(index) == 'p'){
                index ++;
                list.add(ch+"");
            } else if("0123456789".indexOf(str.charAt(index)) >= 0){
                //是数字,判断多位数的情况
                String str1 = "";
                while (index < str.length() && "0123456789.".indexOf(str.charAt(index)) >= 0){
                    str1 += str.charAt(index);
                    index ++;
                }
                list.add(str1);

            }
        }while (index < str.length());
        return list;
    }

    public List<String> houZhui(List<String> list){//中缀表达式转换称后缀表达式
        Stack<String> fuZhan = new Stack<>();
        List<String> list2 = new ArrayList<>();
        if (!list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) {
                if (isNumber(list.get(i))){
                    list2.add(list.get(i));
                } else if (list.get(i).charAt(0) == '('){
                    fuZhan.push(list.get(i));
                } else if (isOperator(list.get(i)) && list.get(i).charAt(0) != '('){
                    if (fuZhan.isEmpty()){
                        fuZhan.push(list.get(i));
                    } else {//符栈不为空
                        if (list.get(i).charAt(0) != ')'){
                            if (adv(fuZhan.peek()) <= adv(list.get(i))){
                                //入栈
                                fuZhan.push(list.get(i));
                            } else {//出栈
                                while (!fuZhan.isEmpty() && !"(".equals(fuZhan.peek())){
                                    if(adv(list.get(i)) <= adv(fuZhan.peek())){
                                        list2.add(fuZhan.pop());
                                    }
                                }
                                if (fuZhan.isEmpty() || fuZhan.peek().charAt(0) == '('){
                                    fuZhan.push(list.get(i));
                                }
                            }
                        } else if (list.get(i).charAt(0) == ')'){
                            while (fuZhan.peek().charAt(0) != '('){
                                list2.add(fuZhan.pop());
                            }
                            fuZhan.pop();
                        }
                    }
                }
            }
            while (!fuZhan.isEmpty()){
                list2.add(fuZhan.pop());
            }
        }
      //   else {
      //      jTextField1.setText("");
     //   }
        return list2;
    }
    public static boolean isOperator(String op){//判断是否为操作符
        if ("0123456789.ep".indexOf(op.charAt(0)) == -1) {
            return true;
        } else {
            return false;
        }
    }
    public static boolean isNumber(String num){//判断是否为操作数
        if ("0123456789ep".indexOf(num.charAt(0)) >= 0) {
            return true;
        } else {
            return false;
        }
    }
    public static int adv(String f){//判断操作符的优先级
        int result = 0;
        switch(f) {
            case "+":
                result = 1;
                break;
            case "-":
                result = 1;
                break;
            case "*":
                result = 2;
                break;
            case "/":
                result = 2;
                break;
            case "^":
                result = 3;
                break;
            case "!":
                result = 4;
                break;
            case "g":
                result = 4;
                break;
            case "l":
                result = 4;
                break;
            case "o":
                result = 4;
                break;
            case "s":
                result = 4;
                break;
            case "c":
                result = 4;
                break;
            case "t":
                result = 4;
                break;

        }
        return result;
    }
      public double math(List<String> list2) {//通过后缀表达式进行计算
        Stack<String> stack = new Stack<String>();
        for (int i = 0; i < list2.size(); i++) {
            if (isNumber(list2.get(i))) {
                    stack.push(list2.get(i));
            } else if (isOperator(list2.get(i))){
                double res = 0;
                if (list2.get(i).equals("+")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = num1 + num2;
                } else if (list2.get(i).equals("-")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = num1 - num2;
                } else if (list2.get(i).equals("*")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = num1 * num2;
                } else if (list2.get(i).equals("/")) {//除数不能为0
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    if (num2 != 0){
                        res = num1 / num2;
                    } else {
                        System.out.println("除数不能为0");
                        //indexYN = 1;
                    }
                } else if (list2.get(i).equals("^")) {
                    double num2 = Double.parseDouble(stack.pop());
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.pow(num1, num2);
                } else if (list2.get(i).equals("!")) {//阶乘必须为自然数
                    double num1 = Double.parseDouble(stack.pop());
                    if (num1 == 0 || num1 == 1){
                        res = 1;
                    } else if (num1 == (int)num1 && num1 > 1){
                        int d = 1;
                        for (int j = (int)num1; j >0; j--) {
                            d *= j;
                        }
                        res = d;
                    } else {
                       System.out.println("阶乘必须为自然数");
                        //indexYN = 1;
                    }
                } else if (list2.get(i).equals("g")) {
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.sqrt(num1);
                } else if (list2.get(i).equals("l")) {//ln的x必须大于0
                    double num1 = Double.parseDouble(stack.pop());
                    if (num1 > 0){
                        res = Math.log(num1);
                    } else {
                       System.out.println("ln的x必须大于0");
                       // indexYN = 1;
                    }
                } else if (list2.get(i).equals("o")) {//log的x必须大于0
                    double num1 = Double.parseDouble(stack.pop());
                    if (num1 > 0){
                        res = Math.log(num1) / Math.log(2);
                    } else {
                       System.out.println("log的x必须大于0");
                        //indexYN = 1;
                    }
                } else if (list2.get(i).equals("s")) {
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.sin(num1);
                } else if (list2.get(i).equals("c")) {
                    double num1 = Double.parseDouble(stack.pop());
                    res = Math.cos(num1);
                } else if (list2.get(i).equals("t")) {//tan的x不能为+-(π/2 + kπ)
                    double num1 = Double.parseDouble(stack.pop());
                    if (Math.cos(num1) != 0){
                        res = Math.tan(num1);
                    } else {
                        System.out.println("tan的x不能为+-(π/2 + kπ)");
                       // indexYN = 1;
                    }
                }
                stack.push("" + res);
            }
        }
        if (indexYN == 0){
            if (!stack.isEmpty()){
                return Double.parseDouble(stack.pop());
            } else {
                return 0;
            }
        } else {
            return -999999;
        }
    }
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值