Last active
March 12, 2020 15:30
-
-
Save junminstorage/dcc59a0d1cb1b44f4ffcf6e2962b5459 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static interface Excel { | |
void put(String cell, Integer value, String formula); | |
int get(String cell); | |
} | |
static class CellNode { | |
String cell; | |
String formula; | |
int value; | |
public CellNode(String c, String f){ | |
cell = c; | |
formula = f; | |
} | |
public CellNode(String c, int v) { | |
cell = c; | |
value = v; | |
} | |
} | |
static class ExcelImpl implements Excel { | |
Map<String, Set<String>> graph; | |
Map<String, CellNode> nodes; | |
Map<String, Integer> result; | |
public ExcelImpl() { | |
graph = new HashMap<>(); | |
nodes = new HashMap<>(); | |
} | |
public void put(final String cell, final Integer value, final String formula) { | |
CellNode node = null; | |
if(formula == null) | |
node = new CellNode(cell, value); | |
else | |
node = new CellNode(cell, formula); | |
nodes.put(cell, node); | |
if(!graph.containsKey(cell)) { | |
graph.put(cell, new HashSet<>()); | |
} | |
if(formula != null) { | |
StringTokenizer st = new StringTokenizer(formula, "*+"); | |
while(st.hasMoreTokens()) { | |
graph.get(cell).add(st.nextToken()); | |
} | |
} | |
} | |
public int get(final String cell) { | |
if(nodes.get(cell)==null) | |
return -1; | |
if(nodes.get(cell).formula == null) | |
return nodes.get(cell).value; | |
result = new HashMap<>(); | |
calculateRec(cell); | |
return result.get(cell).intValue(); | |
} | |
// the dependencies among the cells form a tree, here we | |
// go down the tree via DFS recursion to compute the value for each cell/node | |
// result map store the result of each cell's computed value | |
private int calculateRec(final String cell) { | |
if(result.containsKey(cell)) | |
return result.get(cell); | |
if(nodes.get(cell) == null) //assume the formula is always valid, then this likely a computed value | |
return Integer.valueOf(cell); | |
if(nodes.get(cell).formula == null) { | |
result.put(cell, nodes.get(cell).value); | |
return nodes.get(cell).value; | |
} | |
String formula = nodes.get(cell).formula; | |
Stack<String> operands = new Stack<>(); | |
Stack<Character> operators = new Stack<>(); | |
this.parseFormula(formula, operands, operators); | |
while(!operators.isEmpty()) { | |
char operator = operators.pop(); | |
String cell1 = operands.pop(); | |
String cell2 = operands.pop(); | |
if(operator == '+') { | |
char next = ' '; | |
if(!operators.isEmpty()) | |
next = operators.peek(); | |
if(next == '*') { | |
operators.pop(); | |
String cell3 = operands.pop(); | |
operands.push(String.valueOf(calculateRec(cell3) * calculateRec(cell2))); | |
//put it back | |
operators.push(operator); | |
operands.push(cell1); | |
}else{ | |
operands.push(String.valueOf(calculateRec(cell1) + calculateRec(cell2))); | |
} | |
}else{ | |
operands.push(String.valueOf(calculateRec(cell1) * calculateRec(cell2))); | |
} | |
} | |
int re = Integer.valueOf(operands.pop()); | |
result.put(cell, re); | |
return re; | |
} | |
private void parseFormula(final String formula, final Stack<String> operands, final Stack<Character> operators) { | |
Stack<Character> tempC = new Stack<>(); | |
Stack<String> tempS = new Stack<>(); | |
int i = 0, len = formula.length(); | |
while(i<len) { | |
char c = formula.charAt(i); | |
if(c == '+' || c == '*') { | |
tempC.push(c); | |
}else{ | |
StringBuilder sb = new StringBuilder(); | |
sb.append(c); | |
while(i+1<len && formula.charAt(i+1)!='+' && formula.charAt(i+1)!='*'){ | |
sb.append(formula.charAt(i+1)); | |
i++; | |
} | |
tempS.push(sb.toString()); | |
} | |
i++; | |
} | |
while(!tempC.isEmpty()) | |
operators.push(tempC.pop()); | |
while(!tempS.isEmpty()) | |
operands.push(tempS.pop()); | |
} | |
} |
Author
junminstorage
commented
Mar 12, 2020
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment