Я знаю, что не должен давать вам ответы на ваши домашние задания, но мне нравится рекурсия, поэтому я не смог устоять перед этим. Пожалуйста, потратьте некоторое время на понимание и, возможно, на изменение кода, прежде чем передать его. Умные учителя ищут в StackOverflow, особенно если материал, который вы передаете, на удивление хорош:)
Мне пришлось добавить parent
к LLNode. Вместо родительского атрибута у вас может быть список LLNode в классе NodeParser, где список отслеживает самого последнего отца, деда и т. Д. c.
Новый LLNode:
public class LLNode<T> {
protected LLNode<T> link;
protected LLNode<T> nested;
protected LLNode<T> parent; // New field
protected T info;
public LLNode(T info) {
<old code>
parent = null;
}
<old code>
public void setParent(LLNode<T> parent) {
this.parent = parent;
}
public LLNode<T> getParent() {
return parent;
}
}
А потом парсер (включая рекурсивный принтер!):
public class NodeParser {
private String str;
public static void main(String[] args) {
new NodeParser();
}
public NodeParser() {
this.str = "a b ( c d ( e f ) g ) h ( i j ( k ) l ) m n";
LLNode<Character> topNode = new LLNode<>(null);
parse(topNode, false);
print("", topNode.getLink());
}
private synchronized void parse(LLNode<Character> node, boolean nested) {
if (str.length() == 0) {
return;
}
while (str.charAt(0) == ' ') {
str = str.substring(1);
}
char c = str.charAt(0);
str = str.substring(1);
if (c == '(') {
parse(node, true);
} else if (c == ')') {
parse(node.getParent(), false);
} else if (c >= 'a' && c <= 'z') {
LLNode<Character> nextNode = new LLNode<>(c);
if (nested) {
node.setNested(nextNode);
nextNode.setParent(node);
} else {
node.setLink(nextNode);
nextNode.setParent(node.getParent());
}
parse(nextNode, false);
}
}
private void print(String indent, LLNode<Character> node) {
if (node == null) {
return;
}
System.out.println(indent + node.getInfo());
print(indent + " ", node.getNested());
print(indent, node.getLink());
}
}