聚合变量计数,直到遇到左大括号,将减法视为添加否定变量。递归处理子表达式。
子表达式的内容可以直接聚合到计数中,您只需要正确考虑符号 - 无需为此任务创建实际的表达式树。代码中使用的TreeMap只是JDK中的排序映射实现。
代码利用了当前位置是Reader 状态的一部分这一事实,因此我们可以轻松地在递归调用的右括号之后继续解析,而无需以某种方式将该信息显式地交给调用者。
Java 实现(未经测试):
class Expression {
// Count for each variable name
Map<String, Integer> counts = new TreeMap<>();
Expression(Srring s) throws IOException {
this(new StringReader(s));
}
Expression(Reader reader) throws IOException {
int sign = 1;
while (true) {
int token = reader.read();
switch (token) {
case -1: // Eof
case ')':
return;
case '(':
add(sign, new Expression(reader));
sign = 1;
break;
case '+':
break;
case '-':
sign = -sign;
break;
default:
add(sign, String.valueOf((char) token));
sign = 1;
break;
}
}
}
void add(int factor, String variable) {
int count = counts.containsKey(variable) ? counts.get(variable) : 0;
counts.put(count + factor, variable);
}
void add(int sign, Expression expr) {
for (Map.Entry<String,Integer> entry : expr.counts.entrySet()) {
add(sign * entry.getVaue(), entry.getKey());
}
}
void equals(Object o) {
return (o instanceof Expression)
&& ((Expression) o).counts.equals(counts);
}
// Not needed for the task, just added for illustration purposes.
String toString() {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String,Integer> entry : expr.counts.entrySet()) {
if (sb.length() > 0) {
sb.append(" + ");
}
sb.append(entry.getValue()); // count
sb.append(entry.getKey()); // variable name
}
return sb.toString();
}
}
比较
new Expression("A+B-C").equals(new Expression("A-(-B+C)"))
P.S:添加了一个toString() 方法来更好地说明数据结构。
应该打印1A + 1B + -1C 作为示例。
P.P.P.P.S.:修正、简化、更好的解释。