leetcode770. Basic Calculator IV
此题真可谓是练习编程语言的绝好材料 !
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的更多相关文章
- [LeetCode] Basic Calculator IV 基本计算器之四
Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...
- [Swift]LeetCode770. 基本计算器 IV | Basic Calculator IV
Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...
- 770. Basic Calculator IV
Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...
- [LeetCode] Basic Calculator 基本计算器
Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...
- [LeetCode] Basic Calculator III 基本计算器之三
Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...
- 224. Basic Calculator + 227. Basic Calculator II
▶ 两个四则表达式运算的题目,第 770 题 Basic Calculator IV 带符号计算不会做 Orz,第 772 题 Basic Calculator III 要收费 Orz. ▶ 自己的全 ...
- [LeetCode] 772. Basic Calculator III 基本计算器之三
Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...
- [LeetCode] Basic Calculator II 基本计算器之二
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
- Basic Calculator II
Implement a basic calculator to evaluate a simple expression string. The expression string contains ...
随机推荐
- 算法 递归 迭代 动态规划 斐波那契数列 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 使用Java开发微信公众平台(二)——消息的接收与响应
上一篇文章(http://www.jerehedu.com/fenxiang/171807_for_detail.htm )中,我们学习了使用Java语言开发微信公众平台的第一部分——环境搭建与开发接 ...
- springboot下配置多数据源
摘自: http://blog.csdn.net/wangqingqi20005/article/details/52613055
- IT痴汉的工作现状42-Android越用越慢?立场不同,谈何信任!
大海和我一次闲聊中问,你做安卓这么久.能给我解释一下为什么安卓手机用半年后就变慢吗? 呃... 伟仔还真是头一次听说这么精准的半年就慢的说法. 大海继续说."能不能是厂家有益设置的?哦,也不 ...
- Android -- setWillNotDraw()
干货 处理onDraw()方法不被执行的解决方法: setWillNotDraw(false); 官方文档的解释: If this view doesn't do any drawing on its ...
- linux下性能分析命令[总结]
1.前言 在linux下开发程序,为了追求高性能,经常需要测试程序的性能,包括cpu.内存.io.网络等等使用情况.liunx下提供了众多命令方便查看各种资源的使用情况.经常用的有ps.top.fre ...
- Mongoose vs mongodb native driver – what to prefer?
Paul Shan 7th Jun 2015 Mongoose or mongodb native driver, which one to use? This is one of the ini ...
- You must have a copy of the scp binary locally to use the scp feature
在运行docker-machine scp 命令的时候,报错: "You must have a copy of the scp binary locally to use the scp ...
- Objective-C 简介
很少有人会想到 Objective-C 历史悠久,并且它实际上影响了很多其他的编程技术.比如, Java 编程语言和 Objective-C 就有很多共同点.原因就是在 Objective-C 的早期 ...
- Code faster with Intellij IDEA live templates
Intellij IDEA – in my opinion the most productive IDE for Java – comes with bunch of features helpin ...