Discuss / Java / 第一题 第二题 第三题

第一题 第二题 第三题

Topic source

_崔先生_

#1 Created at ... [Delete] [Delete and Lock User]

第一题几行就能出来。

static String toHex(int n) {
    Stack<String> stack = new Stack<>();
    int remainder;
    for (;n > 0;) {
        remainder = n % 16; n = n / 16;
        stack.push(remainder < 10 ? String.format("%d", remainder) : String.format("%c", 55+remainder));
    }
    String output = "";
    for (;!stack.empty();) output+=stack.pop();
    return output;
}

第二题和第三题的compile适应于多数情况。

static SuffixExpression compile(String exp) {
        // TODO:        Stack<String> outs = new Stack<>();
        Stack<String> signs = new Stack<>();

        Map<String, Integer> level = new HashMap<>();  // 主要是设置好运算符号的优先级
        level.put("+", 1); level.put("-", 1);
        level.put("*", 2); level.put("/", 2); level.put("%", 2); level.put("//", 2);
        level.put("^", 3);  // 这里加入了乘方。
        level.put("(", 4); level.put(")", 4);

        String part = "";
        for (char c : exp.toCharArray()) {
            if (c == ' ')continue;
            String s = String.valueOf(c);
            if (level.containsKey(s)) { //如果是符号,就要判断优先级,进行入栈或者出栈的操作,还要判断好左右括号。
                if (part.length() > 0) outs.push(part); part = "";
                Integer sig = level.get(s);
                while ((!signs.empty()) && sig <= level.get(signs.peek())&&level.get(signs.peek())!=4){ outs.push(signs.pop()); }//两个栈,可以做出队列的效果。
                if (s.equals(")")) {
                    while ((!signs.empty())&&(!signs.peek().equals("("))){ outs.push(signs.pop()); } signs.pop();
                } else { signs.push(s); }
            }else{part += s;}
        }
        if (part.length() > 0) outs.push(part);
        
        for (;!signs.empty();){ // 把栈中的剩余符号压出来
            String p = signs.pop();

            outs.push(p);
        }

        return new SuffixExpression(outs);
    }
}

第二题和第三题的类 和 两个实现方法,应该还有很大优化空间

class SuffixExpression {
    public Stack<String> exp;
    private Exception NullPointerException;


    public SuffixExpression(Stack<String> exp){
        this.exp = exp;
    }
    int execute() {
        // TODO:        
        Stack<Integer> result = new Stack<>();

        for (String s: this.exp){
            boolean isNumber = true; // 假设是数字
            boolean isSign = true;  // 假设是运算符号

            for (int i=0; i< s.length();i++){  // 整个循环判断判断是否是数字,其实可以用正则,但是没学到那呢,所以先不写
                if (!Character.isDigit(s.charAt(i)))
                    isNumber= false;break;
            }
            if (isNumber) { // 这里写的很难受,Python有else语法,但是java没有。
                result.push(Integer.valueOf(s));continue;
            }
            if (!(s.length()==1&&"+-*/^".contains(s))) isSign=false;
            if (isSign){  // 确定是运算符号的话,一定是有两个操作数,也就是栈顶的两个。
                Integer b = result.pop();
                Integer a = result.pop();

                switch (s.toCharArray()[0]){
                    case '+': a += b;break;
                    case '-': a -= b;break;
                    case '*': a *= b;break;
                    case '/': a /= b;break;
                    case '^': a = (Integer) (int)Math.pow(a, b);break;  // 这里是加入的乘方的操作
                }
                result.push(a);
            }
        }
    
          return result.pop();
    }

    int execute(Map<String, Integer> env) throws Exception {
        // TODO:        
        Stack<Integer> result = new Stack<>();

        for (String s: this.exp){
            boolean isNumber = true;
            boolean isSign = true;

            for (int i=0; i< s.length();i++){
                if (!Character.isDigit(s.charAt(i)))
                    isNumber= false;break;
            }
            if (isNumber) {
                result.push(Integer.valueOf(s));continue;
            }
            if (!(s.length()==1&&"+-*/^".contains(s))) isSign=false;

            if (isSign){
                Integer b = result.pop();
                Integer a = result.pop();
                switch (s.toCharArray()[0]){
                    case '+': a += b;break;
                    case '-': a -= b;break;
                    case '*': a *= b;break;
                    case '/': a /= b;break;
                    case '^': a = (Integer) (int)Math.pow(a, b);break;
                }
                result.push(a);
                continue;
            }
            Integer v = env.get(s);
            if (v == null) {
                throw NullPointerException;  // 这里如果得到不到s对应的数字会报错
            }
            result.push(v);
        }

        return result.pop();
    }
}

_崔先生_

#2 Created at ... [Delete] [Delete and Lock User]
level.put("//", 2);  这里其实并不支持

_崔先生_

#3 Created at ... [Delete] [Delete and Lock User]
level.put("%", 2);  余数也不支持,不过很好加

  • 1

Reply