码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode770. Basic Calculator IV

时间:2018-03-04 20:00:31      阅读:304      评论:0      收藏:0      [点我收藏+]

标签:keyset   boolean   return   false   static   leetcode   throw   contain   etc   

此题真可谓是练习编程语言的绝好材料 !


import java.util.*;

class Solution {
class Item {
    Map<String, Integer> vars = new TreeMap<>();
    int k = 1;

    String tos() {
        StringBuilder builder = new StringBuilder();
        List<String> a = new ArrayList<>();
        for (String i : vars.keySet()) {
            for (int j = 0; j < vars.get(i); j++) {
                a.add(i);
            }
        }
        if (a.size() == 0) return "";
        builder.append(a.get(0));
        for (int i = 1; i < a.size(); i++) {
            builder.append("*" + a.get(i));
        }
        return builder.toString();
    }

    Item copy() {
        Item it = new Item();
        it.k = k;
        for (Map.Entry<String, Integer> i : vars.entrySet()) {
            it.vars.put(i.getKey(), i.getValue());
        }
        return it;
    }

    Item mul(Item another) {
        Item ans = new Item();
        ans.k = k * another.k;
        for (Map.Entry<String, Integer> i : vars.entrySet()) {
            ans.vars.put(i.getKey(), i.getValue());
        }
        for (Map.Entry<String, Integer> i : another.vars.entrySet()) {
            if (ans.vars.containsKey(i.getKey())) {
                ans.vars.put(i.getKey(), ans.vars.get(i.getKey()) + i.getValue());
            } else {
                ans.vars.put(i.getKey(), i.getValue());
            }
        }
        return ans;
    }

    int getMi() {
        int s = 0;
        for (int x : vars.values()) {
            s += x;
        }
        return s;
    }

    Item render(Map<String, Integer> eval) {
        Item j = new Item();
        j.k = k;
        for (Map.Entry<String, Integer> i : vars.entrySet()) {
            if (eval.containsKey(i.getKey())) {
                j.k *= Math.pow(eval.get(i.getKey()), i.getValue());
            } else {
                j.vars.put(i.getKey(), i.getValue());
            }
        }
        return j;
    }
}

class Exp {
    List<Item> items = new ArrayList<>();

    Exp add(Exp another) {
        Exp exp = new Exp();
        Map<String, Item> ma = new TreeMap<>();
        for (Item i : another.items) {
            Item j = i.copy();
            exp.items.add(j);
            ma.put(j.tos(), j);
        }
        for (Item i : items) {
            String k = i.tos();
            if (ma.containsKey(k)) {
                ma.get(k).k += i.k;
            } else {
                Item j = i.copy();
                ma.put(k, j);
                exp.items.add(j);
            }
        }
        return exp;
    }

    Exp sub(Exp another) {
        another.mul(-1);
        Exp ans = add(another);
        another.mul(-1);
        ans.mul(-1);
        return ans;
    }

    void mul(int x) {
        for (Item i : items) {
            i.k *= x;
        }
    }

    Exp mul(Exp another) {
        Exp ans = new Exp();
        for (Item i : items) {
            for (Item j : another.items) {
                ans.items.add(i.mul(j));
            }
        }
        return ans;
    }

    @Override
    public String toString() {
        List<String> a = tos(this);
        StringBuilder builder = new StringBuilder();
        for (String i : a) {
            builder.append("+" + i);
        }
        return builder.toString();
    }
}

List<String> tokenize(String expression) {
    List<String> ans = new ArrayList<>();
    for (int i = 0; i < expression.length(); i++) {
        if ("()+-*".indexOf(expression.charAt(i)) != -1) {
            ans.add(expression.charAt(i) + "");
        } else if (Character.isDigit(expression.charAt(i))) {
            int j = i;
            while (j < expression.length() && Character.isDigit(expression.charAt(j))) {
                j++;
            }
            ans.add(expression.substring(i, j));
            i = j - 1;
        } else if (Character.isLetter(expression.charAt(i))) {
            int j = i;
            while (j < expression.length() && Character.isLetter(expression.charAt(j))) {
                j++;
            }
            ans.add(expression.substring(i, j));
            i = j - 1;
        }
    }
    return ans;
}

int getPriority(String i) {
    if (i.equals("*")) return 1;
    if (i.equals("+") || i.equals("-")) return 0;
    if (i.equals("(")) return 2;
    if (i.equals(")")) return -1;
    throw new RuntimeException("无法操作符号" + i);
}

boolean isNumber(String s) {
    for (int i = 0; i < s.length(); i++) {
        if (!Character.isDigit(s.charAt(i))) {
            return false;
        }
    }
    return true;
}

Exp number2Exp(int x) {
    Exp exp = new Exp();
    Item it = new Item();
    it.k = x;
    exp.items.add(it);
    return exp;
}

Exp var2Exp(String var) {
    Exp exp = new Exp();
    Item it = new Item();
    it.vars.put(var, 1);
    exp.items.add(it);
    return exp;
}

Exp calculate(Exp m, Exp n, String op) {
    if (op.equals("*")) return m.mul(n);
    else if (op.equals("+")) return m.add(n);
    else if (op.equals("-")) return m.sub(n);
    throw new RuntimeException("无法处理" + op + "运算");
}

Exp parse(List<String> token) {
    Stack<Exp> num = new Stack<>();
    Stack<String> op = new Stack<>();
    for (String i : token) {
        if (i.equals(")")) {
            while (!op.peek().equals("(")) {
                num.push(calculate(num.pop(), num.pop(), op.pop()));
            }
            op.pop();
        } else if ("+-*(".indexOf(i.charAt(0)) != -1) {
            while (!op.empty() && !op.peek().equals("(") && getPriority(i) <= getPriority(op.peek())) {
                Exp a = num.pop(), b = num.pop();
                String o = op.pop();
                num.push(calculate(a, b, o));
            }
            op.push(i);
        } else if (isNumber(i)) {
            num.push(number2Exp(Integer.parseInt(i)));
        } else {
            num.push(var2Exp(i));
        }
    }
    while (!op.empty()) {
        num.push(calculate(num.pop(), num.pop(), op.pop()));
    }
    return num.pop();
}

Exp render(Exp exp, Map<String, Integer> eval) {
    Exp ans = new Exp();
    for (Item i : exp.items) {
        Item j = i.render(eval);
        ans.items.add(j);
    }
    return ans;
}

Exp sort(Exp exp) {
    //合并同类项
    Map<String, Item> vars = new TreeMap<>();
    for (Item i : exp.items) {
        if (vars.containsKey(i.tos())) {
            vars.get(i.tos()).k += i.k;
        } else {
            vars.put(i.tos(), i);
        }
    }
    //去掉0项
    exp.items = new ArrayList<>();
    for (Item i : vars.values()) {
        if (i.k == 0) continue;
        exp.items.add(i);
    }
    //排序
    exp.items.sort((o1, o2) -> {
        int mi1 = o1.getMi();
        int mi2 = o2.getMi();
        if (mi1 == mi2) {
            return o1.tos().compareTo(o2.tos());
        } else {
            return mi2 - mi1;
        }
    });
    return exp;
}

List<String> tos(Exp exp) {
    List<String> ans = new ArrayList<>();
    for (Item i : exp.items) {
        String it = i.k + "";
        if (i.tos().length() > 0) {
            it += "*" + i.tos();
        }
        ans.add(it);
    }
    return ans;
}


public List<String> basicCalculatorIV(String expression, String[] evalvars, int[] evalints) {
    List<String> token = tokenize(expression);
    Map<String, Integer> eval = new TreeMap<>();
    for (int i = 0; i < evalvars.length; i++) {
        eval.put(evalvars[i], evalints[i]);
    }
    Exp exp = parse(token);
    exp = render(exp, eval);
    exp = sort(exp);
    List<String> ans = tos(exp);
    return ans;
}

void haha() {
    List<String> ans = basicCalculatorIV("a*b+a*b*c*d", new String[]{"b"}, new int[]{2});
    for (String i : ans) {
        System.out.print(i + " ");
    }
}

public static void main(String[] args) {
    Solution s = new Solution();
    s.haha();
}
}

leetcode770. Basic Calculator IV

标签:keyset   boolean   return   false   static   leetcode   throw   contain   etc   

原文地址:https://www.cnblogs.com/weidiao/p/8505541.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!