'Can We Tell the Function Call Between Instances of Same Class is Recursive?
I had a quiz of the OOP Course that runs with Java language. We were asked to create a data structure for text file input like this:
A->ab|Ca|Ba
C->Bb|aB
B->a|b
to create an output like:
(ab|((a|b)b|a(a|b))a|(a|b)a)
input:
A->B|C
C->a|ba
B->b|ab
output:
((b|ab)|(a|ba))
Unfortunately, I can't fully share my solution due to Quiz paper but also we were asked to recursively print the full expansion of the ancestor node (node with head character "A"). I created a Node class to handle parent->children relationships and recursive print with toString method but I got no score from the recursive part of the quiz assignment and I got feedback when I asked, that tells me, the solution is iterative and it is not recursive.
I couldn't accept that since the method is able to call another method that has the same instructions even if it is owned by a Node instance with a child role.
import java.util.ArrayList;
import java.util.HashMap;
public class Node {
private String head;
private ArrayList<ArrayList<Node>> sets;
Node(String c) {
this.head = c;
this.sets = new ArrayList<ArrayList<Node>>();
}
public String getHead() {
return this.head;
}
public boolean hasChildren() {
return sets.size() > 0;
}
// recursively (?) return proper output in context of nodes
@Override public String toString() {
if (!this.hasChildren())
return this.getHead();
String[] parts = new String[sets.size()];
for (int i = 0; i < sets.size(); i++) {
String subs = "";
ArrayList<Node> set = sets.get(i);
for (int j = 0; j < set.size(); j++) {
subs += set.get(j); // subs += ((Node) set.get(j)).toString() || The part that I think add recursive feature to method, it doesn't call itself but calls the same method of Node from a child
}
parts[i] = subs;
}
return "(" + String.join("|", parts) + ")";
}
}
I need more opinions about it. Do you think the toString method is recursive? Which functions we cannot call recursive?
Edit:
There was also an instruction, "do not mind the recursive self calls", this means a case like: B -> a|b|B
From that sentence, I didn't mind the neither termination case nor input filtering so when you input a case like that your Node object takes an indirect call from either a child or itself.
Since there is a probability of receiving a recursive input, there will be a certain amount of ratio of probability upon toString function.
Solution 1:[1]
I am sure I do not fully understand your problem, but when reading over it, this is how I envision a workable solution. Of course, the code is not there to load the data, but this Node class would represent the inputs from what I can tell.
So to answer your question, no, the toString() function is not recursive, but interative.
To show that this is a correct assumption, here are the classes which produces the following output. Please note that I included two solutions: one which is iterative, and the other is recursive. I kept the recursive solution as close to the toString() as possible so you can see the differences.
Iterative output:
((b|ab)|(a|ba))
Recursive output:
((b|ab)|(a|ba))
import java.util.ArrayList;
public class Node
{
private String head;
private ArrayList<Node> sets;
public Node( String head ) {
super();
this.head = head;
this.sets = new ArrayList<>();
}
public String toString() {
StringBuilder sb = new StringBuilder();
if ( getSets().size() > 0 ) {
for ( Node set : getSets() )
{
if ( sb.length() > 0 ) {
sb.append( "|" );
}
sb.append( set.toString() );
}
sb.insert( 0, "(" );
sb.append( ")" );
}
else {
sb.append( getHead() );
}
return sb.toString();
}
public String expandChildren() {
return expandChildrenRecursive( this );
}
private String expandChildrenRecursive( Node node ) {
StringBuilder sb = new StringBuilder();
if ( node.getSets().size() > 0 ) {
for ( Node set : node.getSets() )
{
if ( sb.length() > 0 ) {
sb.append( "|" );
}
sb.append( expandChildrenRecursive( set ) );
// sb.append( set.toString() );
}
sb.insert( 0, "(" );
sb.append( ")" );
}
else {
sb.append( node.getHead() );
}
return sb.toString();
}
public String getHead() {
return head;
}
public void setHead( String head ) {
this.head = head;
}
public ArrayList<Node> getSets() {
return sets;
}
public void setSets( ArrayList<Node> sets ) {
this.sets = sets;
}
}
Now here is the class I used to build the objects so I can test it.
public class NodeTest
{
public static void main ( String[] args ) {
Node nodeB = new Node("B");
nodeB.getSets().add( new Node("b") );
nodeB.getSets().add( new Node("ab") );
Node nodeC = new Node("C");
nodeC.getSets().add( new Node("a") );
nodeC.getSets().add( new Node("ba") );
Node nodeA = new Node("A");
nodeA.getSets().add( nodeB );
nodeA.getSets().add( nodeC );
System.out.println( "Iterative output:" );
System.out.println( nodeA.toString() );
System.out.println( "\nRecursive output:" );
System.out.println( nodeA.expandChildren() );
}
}
Hopefully that does help to answer your question on how it is actually iterative and how a recursive solution is slightly different.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
