Суммарная переменная рассчитывает до появления открывающей фигурной скобки, рассматривая вычитание как добавление отрицательной переменной. Обрабатывать подвыражения рекурсивно.
Содержимое подвыражений может быть напрямую объединено в счетчики, вам просто нужно правильно учесть знак - для этой задачи нет необходимости создавать фактическое дерево выражений. 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.: Исправления, упрощение, лучшее объяснение.