Problem using recursive function to compare trees in Java

Hi

I have to find the best matching subtrees in two xml trees.
here is the code (in brief):

public static void FindBestMatchingSubtree(int doc1, int doc2, Node n1, Node n2, SQLScript statement) {
        // retrieve internal nodes for the first and second trees  
        
        ArrayList<Node> t1Nodes = statement.getInternalChildNodes(doc1, n1);
        ArrayList<Node> t1Nodes = statement.getInternalChildNodes(doc2, n2);

        for (Node t1childNode : t1Nodes) {  // to iterate child nodes of the 1st ArrayList
            for (Node t2childNode : t2Nodes) {  // to iterate child nodes of the 2nd ArrayList
                
                if (t1childNode.getNodeName().equals(t2childNode.getNodeName())) {
                    score = calculateScore(t1childNode, t2childNode, statement);
                    
                    // Test if two pair of nodes for the two trees are matched
                    if (score == 1.0) { // Identical nodes
                        System.out.println("Identical");
                    }
                    else if ((score < 1.0) && (score > 0)) { // Matched nodes (semi)
                        System.out.println("Matched");
                        // recursively match the child nodes of the current ones 
                        FindBestMatchingSubtree(doc1, doc2, t1childNode, t2childNode, statement);    
                    }
                } // end if

            }  // end for
            // Just hint for the output
            System.out.println("Finish one child from the first tree");
        }  // end for
    }

Open in new window


Job of the function:
- It takes as input two document ids and two nodes of them (say root nodes of XML document.
- It then create two ArrayLists of child nodes for both given nodes n1 & n2.
- It will then compare pairs of nodes to find if they are Identical or matched (using special function calculateScore).
- If they are identical, print that.
- If they are matched (not exactly the same), go deeper and repeat the process by comparing child nodes of the current pair.

The problem:
I get wrong result because I think when the function (FindBestMatchingSubtree) is called inside itself it will repeat creating the two ArrayLists: t1Nodes & t2Nodes, which is wrong

Can anyone help to achieve the goal without having such a problem

Regards
hamsalglaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

anilallewarCommented:
The array lists t1Nodes & t2Nodes that are created with each recursive call is fine as those would be different objects that get created on stack.

What is the significance of int doc1, int doc2 as they get passed for each recursive call but don't change within the execution?

I will need more information including the code to make further suggestions.
0
gatorvipCommented:
>>I get wrong result

How can you tell? Please post sample data, the resulting output using your code and the desired output
0
gatorvipCommented:
>>       ArrayList<Node> t1Nodes = statement.getInternalChildNodes(doc1, n1);
        ArrayList<Node> t1Nodes = statement.getInternalChildNodes(doc2, n2);

Check your code, this should probably say t2Nodes. I assume this is just a copy/paste typo in here as in real code you should be getting an error (t2Nodes would be undefined).
0
hamsalglaAuthor Commented:
What is the significance of int doc1, int doc2 as they get passed for each recursive call but don't change within the execution?

doc1 and doc2 are passed as parameters getInternalChildNodes function to get the list of nodes for doc1 and doc1 (see line 4 and 5).
They do not affect the results.

>>       ArrayList<Node> t1Nodes = statement.getInternalChildNodes(doc1, n1);
        ArrayList<Node> t1Nodes = statement.getInternalChildNodes(doc2, n2);

Check your code, this should probably say t2Nodes. I assume this is just a copy/paste typo in here as in real code you should be getting an error (t2Nodes would be undefined).

Yes I made a typo mistake.

Actually I found the problem. that is a exit from the function:
if (t1Nodes.isEmpty() || t2Nodes.isEmpty()) {
            System.exit(0);
}

Open in new window

It was in line 9 (inside the two loops)
I remove it from the code here because I thought it is not significant.
When I replace it with If..Else condition, the program works fine and I get the correct results.

Thanks guys for your helps.

I will back to you as soon as i have probs since this is just a very small part of my big project :)

Regadrs
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
hamsalglaAuthor Commented:
Calling 'System.exit()' inside the function can be a good practice as long as you know it will not end the program unexpectedly.

Use 'if, else' statement instead.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Algorithms

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.