Java入门 1. 中缀表达式转后缀表达式

总结:
  • 提取字符串要用char的值来逐一判断,java中使用ASC II值存储,例如通过一下表达式,可以直接输出ASC II值
(int)expression.charAt(index) < 48
  • Java中字符以2个字节存储
Character ch = 'A';
System.out.println(Character.getNumericValue(ch)); // 直接将字符串转化为显示的数值 如0对应的就是0, A对应10
System.out.println((int)ch);
  • 多次地方在循环条件中添加特殊判断,以防止溢出,且均放在if条件中最前面直接判断:
map.get(formula.peek()) != null; // 判断栈不为空,否则返回nulll
index < expression.length();// 防止溢出
formula.size() != 0 ;//判断不为空
遗留问题:

1)为什么字符串栈的的时候不能直接相等,例如以下在表达式可以存在,放到方法中是fales

formula.peek() == "*")

而是必须使用

formula.peek().equals('"*");
转换实现代码:
import java.util.*;

public class StackSufflix {

    public static void main(String[] args) {
        String exp = "1 + 2 * (9 - 4)";
        String exp1 = "1 + 3";
        String exp2 = "(3 + 8) * 2 - 1";
        String exp3 = "(1 + 2 * (9 - 5) )";

        List suffixtest = List.of("1","+","2","*","(","9","-","5",")");
        System.out.println("Correct" +suffixtest);

        SuffixExpression se = compile(exp3);
        int result = se.execute();
        System.out.println(exp + " = " + result + " " + (result == 1 + 2 * (9 - 5) ? "✓" : "✗"));

        // 以下是代码测试
        char test = '1';
        System.out.println("'1' asc ii is "+ (int)test); // 输出ASC II 值
        String test1 = String.valueOf(test);
        //System.out.println(test1.equals("1"));
        //List list = expressionToList(exp);
        //for(String s :list){
            //System.out.println("提取符号后 "+s);
        //}


    }

    static SuffixExpression compile(String ex) {
        List element = new ArrayList<>(); // 存储表达式中元素符号
        List midffix = new ArrayList<>(); // 存储中缀表达式
        List suffix1 = new ArrayList<>(); // 存储后缀表达式

        suffix1 = midTosuffix(ex);

        return new SuffixExpression(suffix1);
    }


    // 中缀表达式转换为后缀表达式
    static List midTosuffix (String expression){
        List mid = expressionToList(expression);
        System.out.println("mid is "+mid);

        List suffix = new ArrayList<>();
        Deque formula = new LinkedList<>();// 栈存储符号与计算方式
        Map map = new HashMap<>();

        map.put("+",1);
        map.put("-",1);
        map.put("*",2);
        map.put("/",2);
        map.put("(",3); // 相当于优先级最高,用于比较
        //System.out.println("test map "+(map.get("+") == map.get("-")));
        System.out.println("size "+formula.size());

        List midtest1 = List.of("1","+","2","*","(","9","-","5",")");
        List midtest2 = List.of("2","*","(","3","+","4",")");
        List midtest3 = List.of("(","13","+","4",")","*","2");

        for(String element: mid){
            System.out.println("-----------------------");
            System.out.println("后缀队列 "+suffix);
            System.out.println("计算栈 "+formula+"栈顶为 "+ formula.peek());
            //System.out.println("Formula "+(formula.peek() == "*")); // 为什么这里不能相等?
            System.out.println("当前符号 "+element);

            if(element.equals("+")  || element.equals("-") || element.equals("*")|| element.equals("/")){
                if(formula.size() != 0 && (formula.equals("+") || formula.peek().equals("-") || formula.peek().equals("*") || formula.peek().equals("/"))){
                    // 防止栈为空,euqals时会报错,加上一句对formula 栈的是否为空的检查
                    while (map.get(formula.peek()) != null && map.get(element) <= map.get(formula.peek())){ // 防止栈空取不到优先级,加限制条件
                        System.out.println("Its 符号比较场景 "+ formula.peek());
                        suffix.add(formula.pop());
                        System.out.println("优先级比较后栈 "+formula);
                    }
                    System.out.println("优先级高的添加后 再添加 "+element);
                    formula.push(element);
                }else { // 栈为空的情况,直接入栈
                    System.out.println("栈为空 直接入栈 运算符号 "+element);
                    formula.push(element);
                }
            }else if(element.equals("(")){
                System.out.println("Its (");
                formula.push(element);

            }else if(element.equals(")")){
                System.out.println("Its )");
                for(;;){
                    if(formula.peek().equals("(")) {
                        formula.pop(); // 遇到左括号直接删除
                        System.out.println("成功弹出 (");
                        break; // 退出循环
                    }
                     // 遇到不是左括号的,直接添加到队列中
                    System.out.println("弹出 符号(前的: "+formula.peek());
                    suffix.add(formula.pop());
                }

            }else {
                System.out.println("Number "+ element+" added");
                suffix.add(element);
            }
        }
        System.out.println("------------------");
        System.out.println("最终 队列:"+suffix);
        System.out.println("最终 栈: "+formula+"长度 "+formula.size());
        System.out.println("------------------");

        while (formula.size() != 0){
            suffix.add(formula.pop());
        }
        System.out.println("*********************");
        System.out.println("最终 队列:"+suffix);
        System.out.println("最终 栈: "+formula+"长度 "+formula.size());
        System.out.println("*********************");

        return suffix;
    }

    // 提取表达式中字符串与括号
    static List expressionToList (String expression){
        List cache = new ArrayList<>();
        int index = 0;

        label:for(;index < expression.length();){

            if(expression.charAt(index) == ' '){
                index = index + 1;
                System.out.println("遇到空格");
                System.out.println("空格 Index is "+index);
                continue label;
            }
            if((int)expression.charAt(index) < 48 ||(int)expression.charAt(index) > 57 ){ // asc ii 0 对应48,9对应57
                cache.add(String.valueOf(expression.charAt(index)));
                System.out.println("Symbol is "+String.valueOf(expression.charAt(index)));
                //System.out.println("Symbol is string ? "+String.valueOf(expression.charAt(index)).equals("+"));
                index = index + 1;
            }else {
                String number = "";
                while (index < expression.length() && (int)expression.charAt(index) > 47 && (int)expression.charAt(index) < 58){
                    number = number + String.valueOf(expression.charAt(index));
                    index = index + 1;
                    System.out.println("Number index is "+index);
                }
                cache.add(number);
                System.out.println("number is "+number);
            }
        }
        System.out.println("Cache "+cache);
        return cache;
    }
}

class SuffixExpression { // 需要写构造方法
    public String suffixexp;
    List suffix = new ArrayList<>(); // 存储后缀表达式
    Deque cache = new LinkedList<>(); // 存储计算的
    List suffixtest = List.of("1","2","3","+","4","*","+","5","-"); // ("1","2","3","+","4","*","5","-","+"); 结果是一样的

    public SuffixExpression(List suffix){
        this.suffix = suffix;
    }

    int execute() {
     // 计算后缀的值
    for(String s: suffix){
        if(s.equals("*") | s.equals("/") | s.equals("+") | s.equals("-")){
            String formula = s;
            Integer first = cache.pop();// 倒数第一个
            Integer second = cache.pop();// 倒数第二个
            switch (formula){
                case "*":
                    cache.push(second*first);
                    break;
                case "/":
                    cache.push(second/first);
                    break;
                case "+":
                    cache.push(second+first);
                    break;
                case "-":
                    cache.push(second-first);
                    break;
            }
            //System.out.println("Its formula"+cache.peek());
        }else {
            Integer newvalue = Integer.valueOf(s);
            cache.push(newvalue);
            //System.out.println("Its number"+cache.peek());
        }
    }
        //System.out.println(cache.peek()); // 打印最后的值,检查是否正确
        Integer result1 = cache.pop(); // 返回最终结果
        System.out.println("result1 is "+result1);
        return result1;

    }
}


你可能感兴趣的:(Java入门 1. 中缀表达式转后缀表达式)