'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