中缀表达式转后缀表达式-栈实现简单的计算器功能

主要思路来自于尚硅谷

本文是随便写的没什么很逻辑的结构,不同的人根据中缀表达式写的不太一样,但是利用同样的计算方法结果相同,大概是数相加或者相减的顺序不同。
此代码没有经过很多数据的测试,可能某些条件没写好,很可能有bug,发现时还望在评论区留言共同进步。

/**
 * 用链表实现的栈;
 * */
public class LinkedStack {
    class StackNode {
        public Object o = null;
        public StackNode next = null;

        StackNode(Object o) {
            this.o = o;
        }

        StackNode() {
            this(null);
        }

        @Override
        public String toString() {
            return "" + this.o;
        }
    }

    private StackNode head = null;
    private int length = 0;

    public LinkedStack() {
        this.head = new StackNode();
        this.length = 0;
    }

    public boolean isEmpty() {
        return this.length == 0;
    }

    public int size() {
        return this.length;
    }

    public void push(Object o) {
        StackNode stackNode = new StackNode(o);
        stackNode.next = this.head.next;
        this.head.next = stackNode;
        this.length++;
    }

    public Object top() {
        if (this.isEmpty()) {
            throw new RuntimeException("此栈为空");
        }
        return this.head.next.o;
    }

    public Object pop() {
        if (this.isEmpty()) {
            throw new RuntimeException("此栈为空");
        }
        StackNode stackNode = this.head.next;
        this.head.next = stackNode.next;
        this.length--;
        return stackNode.o;
    }

    public String traverse() {
        StackNode stackNode = this.head.next;
        String string = "";
        int flag = 0;
        while (stackNode != null) {
            if (flag++ == 0) {
                string = string + stackNode;
            } else {
                string = string + ", " + stackNode;
            }
            stackNode = stackNode.next;
        }
        return string;
    }

    public void reverse() {
        if (this.length == 0 || this.length == 1) {
            return;
        }
        StackNode p = this.head;
        StackNode q = this.head.next;
        StackNode temp = null;
        while (q != null) {
            temp = q.next;
            q.next = p;
            p = q;
            q = temp;
        }
        this.head.next.next = null;
        this.head.next = p;
    }

    @Override
    public String toString() {
        return "LinkedStack{" +
                "length=" + length +
                ", values=(" + this.traverse() +
                ")}";
    }
}

import java.util.*;

import LinkedStack;

public class PolandNotation {

    public List<String> symbols = new ArrayList<String>();
    /*此类上一次计算的后缀表达式*/
    public String lastpostfix = null;

    PolandNotation() {
        /**
         * 定义几种运算符的优先级,如果另有需要可以修改
         * 实在不行重写 this.compareTo()规定各种符号的优先级
         */
        this.symbols.add("+");
        this.symbols.add("-");
        this.symbols.add("*");
        this.symbols.add("/");
        this.symbols.add(")");
        this.symbols.add("(");
    }

    public Double calculate(String original) {
        /**
         * original:源表达式
         */
        LinkedStack linkedStack = this.infixToSuffix(original);
        this.lastpostfix = linkedStack.traverse().replace(",", "");
        LinkedStack result = new LinkedStack();
        while (!linkedStack.isEmpty()) {
            if (linkedStack.top() instanceof Double) {
                result.push(linkedStack.pop());
            } else {
                double y = (Double) result.pop();
                double x = (Double) result.pop();
                result.push(this.calcResult(x, y, (String) linkedStack.pop()));
            }
        }
//        System.out.println(result);
        return (Double) result.top();
    }

    public LinkedStack infixToSuffix(String original) {
        /**
         * 该方法将前缀表达式转化为后缀表达式
         * 字符串的处理中主要用了正则表达式,比较简略
         * */
        Object[] expression = original.replaceAll("[+*/()-]{1}", " , ").split(" ");
        Object[] string2 = original.replaceAll("[0-9]+", "").split("");
        expression = this.processString(expression);
        string2 = this.processString(string2);
        for (int i = 0, j = 0; i < expression.length; i++) {
            if (",".equals(expression[i])) {
                expression[i] = string2[j++];
            }
        }
        /*将两个分开的数字部分和运算符部分合成一个Object数组*/
        for (int i = 0; i < expression.length; i++) {
            try {
                expression[i] = Double.valueOf((String) expression[i]);
            } catch (RuntimeException e) {
                continue;
            }
        }
        LinkedStack polandstack = new LinkedStack();
        LinkedStack tempstack = new LinkedStack();
        /*视频中讲的各种条件-可能顺序不太一样*/
        for (int i = 0; i < expression.length; i++) {
            if (expression[i] instanceof Double) {
                polandstack.push(expression[i]);
            } else {
                if (tempstack.isEmpty() || "(".equals(expression[i]) || "(".equals(tempstack.top())) {
                    tempstack.push(expression[i]);
                    continue;
                }
                if (")".equals(expression[i])) {
                    while (!"(".equals(tempstack.top())) {
                        polandstack.push(tempstack.pop());
                    }
                    tempstack.pop();
                    continue;
                }
                while (!tempstack.isEmpty()) {
                    if (this.compareTo(expression[i], tempstack.top())) {
                        tempstack.push(expression[i]);
                        break;
                    } else {
                        polandstack.push(tempstack.pop());
                    }
                }
            }
        }
        while (!tempstack.isEmpty()) {
            polandstack.push(tempstack.pop());
        }
        polandstack.reverse();
        return polandstack;
    }

    public Object[] processString(Object[] strings) {
        /**
         * 去除各种空串或者空格
         */
        List<Object> list = new ArrayList<>();
        for (Object string : strings) {
            if ("".equals(string) || " ".equals(string) || ".".equals(string)) {
                continue;
            }
            list.add(string);
        }
        return list.toArray();
    }

    public Boolean compareTo(Object s1, Object s2) {
        /**
         * 优先级的比较
         */
        return this.symbols.indexOf(s1) > this.symbols.indexOf(s2);
    }

    public double calcResult(double x, double y, String string) {
        /**
         * 基本表达式的运算
         */
        if ("+".equals(string)) {
            return x + y;
        } else if ("-".equals(string)) {
            return x - y;
        } else if ("*".equals(string)) {
            return x * y;
        } else {
            return x / y;
        }
    }
}

public class Main {
    public static void main(String[] args){
        PolandNotation polandNotation = new PolandNotation();
        String string = "1+((2+3.0)*4)- 5.5";
        System.out.println(polandNotation.calculate(string));
        System.out.println("中缀表达式: " + string);
        System.out.println("转化后的后缀表达式: " + polandNotation.lastpostfix);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值