Recursively Traversing XML DOM Tree in Java - java

I am new to Java Programming. I have written a recursive procedure as follows:
public static String treeWalk2(Element element, String tofind) {
String result = "";
for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
Node node = element.node(i);
if ( node instanceof Element ) {
result = treeWalk2( (Element) node, tofind );
}
else {
if (node.asXML().toLowerCase().equals(tofind)) {
result = node.getUniquePath();
System.out.println(node.getUniquePath());
break;
}
}
}
return result;
}
I am trying to find an element in DOM Tree matching some string ("tofind" parameter in the procedure). If the type of the current node is an instance of Element then it will call itself. But when the value of the node is equal to "tofind" string then it will return the unique path of that node. I tried it with an xml file but the return value of the procedure is always "". You can see in the code I also write the unique path, if found, to the screen and it is giving me the desired result. Can anyone tell me what is wrong with my code? Thank you.

I would suggest to use return instead of break; like below
if (node.asXML().toLowerCase().equals(tofind)) {
result = node.getUniquePath();
System.out.println(node.getUniquePath());
return node.getUniquePath();
}

Related

Find and return a Node in Binary Tree Java

Hi I'm trying to find a node equal to a string given by parametres and return that node. My structure is a binary tree of strings. We assume that the string searched exists.
The var q is inicializated to the root of the tree. (in the function I called the method find)
private NodeTree find(NodeTree q, String cont){
if(q._contingut.equals(cont)) return q;
else {
if(q._left!=null) return find(q._left,cont);
else if(q._right!=null)return find(q._right,cont);
}
return null;
}
In line 4 of the find() function you shouldn't return the result of recursive call over left subtree. Instead you should search the right subtree for the string if you get "NULL" from the left subtree.
Here is the updated code
private NodeTree find(NodeTree q, String cont){
if(q==NULL) return NULL;
if(q._contingut.equals(cont)) return q;
NodeTree result = NULL;
if(!q._left) result = find(q._left,cont);
if(!result && q._right) result = find(q._right,cont);
return result;
}
If your BST is built correctly, you need to decide where to look (left or right subtree) comparing current node value to query value, something like:
NodeTree find(NodeTree q, String query) {
if(q.value.equals(query))
return q;
else if (q.value.compareTo(query) > 0)
return q.left == null ? null : find(q.left, query);
else
return q.right == null ? null : find(q.right, query);
}

Binary Search tree - insertion

You are given a pointer to the root of a binary search tree and a value to be inserted into the tree. Insert this value into its appropriate position in the binary search tree and return the root of the updated binary tree. You just have to complete the function.
I have given my code but one test case is not working. Here is my code:
static Node Insert(Node root,int value){
Node d =root;
Node q = new Node();
q.left = null;
q.right=null;
q.data = value;
while(true){
if(value<d.data){
if(d.left==null){d.left = q;
return root; }
else{
d= d.left ;
}
}
else{
if(value>d.data){
if(d.right==null){d.right=q;
return root;}
else d = d.right;
}
}
}
}
You're missing two cases: value == d.data and the empty tree.
value == d.data: In that case the tree won't be altered in any way, but your code won't break-off and end up in an infinite loop.
Simplest solution would be to insert these lines in the while-loop:
if(value == d.data)
return root;
The case where the tree is empty is rather implementation-specific, so it's difficult to suggest any solution for this case.

How to add an element to a linked list?

So a method for part of a project requires that I check to see that an E element is already in the node list. If not, then I add the element to the list and return true (as the method is type boolean). However, I keep getting an error in my JUnit test class. So I wanted to know what is wrong with my code currently. Here is the method:
public boolean add(E element)
{
for(Node ref = first; ref != null; ref = ref.next)
{
first = new Node(element);
if(!(element.equals(ref.data)))
{
n++;
add(element);
return true;
}
else if(element.equals(ref.data))
{
return false;
}
}
return false;
}
I'm pretty sure that the way I formatted the code is wrong. I'm not really familiar with nodes as I am with arrays so that is the reason why the code may be a disgrace. And btw, n is for size.
Your method appears to be combining both a recursive approach and an iterative approach to search, and in neither case do you handle the actual adding of the new element to the list.
You didn't specify where the new element should be added (front or back), so I'll assume front. I'm also assuming that first in your code is a field of your class, because it isn't otherwise declared.
A recursive solution doesn't make much sense here and doesn't have any advantages that I can see in this case. So here's one iterative solution, which puts the new element in front if not found:
public boolean add(E element)
{
for (Node ref = first; ref != null; ref = ref.next)
{
if (element.equals(ref.data)) {
return false;
}
}
Node newFirst = new Node(element);
newFirst.next = first;
first = newFirst;
return true;
}
The logic should have two parts:
First check in the complete list if the element exists or not? If it does return false and dont do anything else go to step 2.
If element does not exist then insert it and return true.
This is shown in the following code:
public boolean add(E element)
{
boolean doesElementExist = false;
//Step 1
for(Node ref = first; ref != null; ref = ref.next)
{
if(element.equals(ref.data))
{
doesElementExist = false;
break;
}
}
//Step 2
if(!doesElementExist) {
// Now we need to add element.
Node newNode = new Node(element);
newNode.next = first;
first = newNode;
doesElementExist = true;
}
return doesElementExist;
}

Recursive tree encryption method using dfs

This problem is not for an assignment, although it's a somewhat typical "assignment-like" problem that I'm trying to solve in a different way.
I want to write a method that will recursively go through a binary tree using a depth-first search algorithm to find a match for a character. Once it finds the matching character, I want it to return a string that maps the position of the character in the tree using 0s and 1s. "001",for example, would indicate that the character is found by going to the left node of the root node, the left node of that node, and then to the right node of that node.
Here is the code I have so far:
private static String encryptSearch(char c, BinaryNode curNode, String result)
{
char data = (char) curNode.getData();
if (data != c)
{
if (curNode.hasLeftChild())
{
result = result + "0";
encryptSearch(c, curNode.getLeftChild(), result);
}
if (curNode.hasRightChild())
{
result = result + "1";
encryptSearch(c, curNode.getRightChild(), result);
}
result = result.substring(0, result.length()-1);
}
return result;
}
The method is initially sent the character to be searched for, the root node, and null for the result. This method returns nothing except 0s. I think there are multiple problems with my code, but the largest one is that when the search reaches a leaf node, it returns. I've been unable to think of a way around this problem while still returning a string. I could easily write a void method that acts on the result string as an external variable, but I don't want to do that for the purpose of the exercise. Any help is appreciated!
Use the mutable StringBuilder instead of String. Also there should be a way to know that you got the result from left one (if any) before searching right one. So I suggest following changes.
private static boolean encryptSearch(char c, BinaryNode curNode, StringBuilder result) {
char data = curNode.getData();
if (data != c) {
boolean found = false;
if (curNode.hasLeftChild()) {
found = encryptSearch(c, curNode.getLeftChild(), result);
if (found) {
result.insert(0, "0");
return true;
}
}
if (curNode.hasRightChild()) {
found = encryptSearch(c, curNode.getRightChild(), result);
if (found) {
result.insert(0, "1");
return true;
}
}
return false; //no result
}
return true;
}

Recursive method returning a string at each step?

I have a slight algorithmic problem. I think I miss something but can't exactly figure out what.
I want to walk to a tree containing strings and get out with a unique string.
Here is a graphical example of a tree I would like to parse.
My trees would have three different types of elements :
Boolean operators (OR, NOT, AND) => BE
other operators (like the =) => QO
leaves (last elements) =>LEAF
I would like to end up with something like this :
"LEAF QO LEAF BE LEAF QO LEAF "
For now, I use a recursive method: I check the current element of the tree, and re run the method on its children depending on the type of elements I have. For each step I would populate my final string.
public class SingleTest {
static String[] booleanElements = {"or", "and", "not"};
public static void main(String[] args) throws Exception {
CommonTree tree = (CommonTree)parser.parse().getTree();
if(true){
String where = "";
printWhere(tree, where);
System.out.println(where);
}
}
/*
* Print to where tests
*/
public static boolean isBooleanElement(CommonTree t){
return Arrays.asList(booleanElements).contains(t.toString().toLowerCase());
}
public static String printWhere(CommonTree t, String where){
//---------------------
// Checking node type
//---------------------
// Boolean Element
if (isBooleanElement(t)){
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
printWhere((CommonTree)t.getChild(i), where+ "BE");
}
}
// Last element of tree (LEAF)
else if(t.getChildCount() == 0 ){
where = where + "LEAF";
}
// query operator
else{
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
printWhere((CommonTree)t.getChild(i), where + "QO");
}
}
//---------------------
return where;
}
My problem is that this code :
String where = "";
System.out.println(printWhere(tree, where));
returns "" (Which is logical due to my implementation).
So my question is, how can I get to have a non void string as final output ?
Hope this is clear enough
Thank you for your help
Please note that this class is used for test purpose only, and I know that putting static everywhere is bad practice :)
EDIT :
The problem was (as expected) due to my lack of experience with recursion.
Here is my final code :
public static String printWhere(CommonTree t, String where){
//---------------------
// Checking node type
//---------------------
// Boolean Element
if (isBooleanElement(t)){
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
where = printWhere((CommonTree)t.getChild(i), where) + "BE";
}
}
// Last element of tree (LEAF)
else if(t.getChildCount() == 0 ){
where = where + "LEAF";
}
// query operator
else{
// Continue parsing the tree
for ( int i = 0; i < t.getChildCount(); i++ ) {
where = printWhere((CommonTree)t.getChild(i), where ) + "QO";
}
}
//---------------------
return where;
}
The problem is that you method printWhere does not return anything! You're appending the value to new where string, but since Java passes parameters by value, this newly created string is thrown away when you leave the method.
Make this method return string and return where at the end of it. Then, concatenate the result of a recursive call with the string from the above level. That's how recursion works.

Categories

Resources