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


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的更多相关文章

  1. [LeetCode] Basic Calculator IV 基本计算器之四

    Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...

  2. [Swift]LeetCode770. 基本计算器 IV | Basic Calculator IV

    Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...

  3. 770. Basic Calculator IV

    Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...

  4. [LeetCode] Basic Calculator 基本计算器

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  5. [LeetCode] Basic Calculator III 基本计算器之三

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  6. 224. Basic Calculator + 227. Basic Calculator II

    ▶ 两个四则表达式运算的题目,第 770 题 Basic Calculator IV 带符号计算不会做 Orz,第 772 题 Basic Calculator III 要收费 Orz. ▶ 自己的全 ...

  7. [LeetCode] 772. Basic Calculator III 基本计算器之三

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  8. [LeetCode] Basic Calculator II 基本计算器之二

    Implement a basic calculator to evaluate a simple expression string. The expression string contains ...

  9. Basic Calculator II

    Implement a basic calculator to evaluate a simple expression string. The expression string contains ...

随机推荐

  1. Android -- WebView进度条

    有系统actionbar requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);//先给Activity注册界面进度条功能 setCo ...

  2. 论文列表——text classification

    https://blog.csdn.net/BitCs_zt/article/details/82938086 列出自己阅读的text classification论文的列表,以后有时间再整理相应的笔 ...

  3. 推荐系统resys小组线下活动见闻2009-08-22

    http://www.tuicool.com/articles/vUvQVn 时间2009-08-30 15:13:22  不周山原文  http://www.wentrue.net/blog/?p= ...

  4. Mahout 安装配置

    http://log.medcl.net/item/2011/02/mahout_install/ Apache Mahout是一个机器学习的框架,构建在hadoop上支持大规模数据集的处理,目前最新 ...

  5. ASP入门(十五)- Global.asa

    Global.asa 文件是一个可选文件,它可包含被 ASP 应用程序中每个页面访问的对象.变量和方法的声明.所有合法的浏览器脚本都可以在 Global.asa 中使用. Global.asa 文件只 ...

  6. Robot Framework + Selenium library + IEDriver环境搭建

    转载:https://www.cnblogs.com/Ming8006/p/4998492.html#c.d 目录: 1 安装文件准备2 Robot框架结构3 环境搭建  3.1 安装Python  ...

  7. Springboot项目启动报错,提示Cannot determine embedded database driver class for database type NONE

    我在springboot项目里面引入了数据库的配置: <dependency> <groupId>org.mybatis.spring.boot</groupId> ...

  8. 【转】开发者可以使用Docker做什么?

    有些开发者可能还是不明白 Docker 对自己到底有多大的用处,因此翻译 Docker 个人用例 这篇文章中来介绍 Docker 在普通开发者开发过程中的用例. Docker 如今赢得了许多关注,很多 ...

  9. sql语句查询某一天数据

    --如果还有今天以后的数据 --一周内呢SELECT * FROM TB WHERE datediff(dd,DATE_TIME,getdate()) between 0 and 7 --从现在起往前 ...

  10. loadscript加载

    function load_script(xyUrl, callback){ var head = document.getElementsByTagName('head')[0]; var scri ...