How to exit while cycle with recursive method inside it? - java

Here is the problem I can not resolve. I have an .xml file, not with parent and child but with grand-child and multi-grand child. Every element name is unique, so I need a method to find and return searchable element. My code so far:
public static Element findElement(Element current, String nameOfElement) {
Element searchedElement = null; // this element I want to return
List children = current.getChildren(); // current is a root element passed to method
Iterator iterator = children.iterator();
//label:
while (iterator.hasNext()) {
Element child = (Element)iterator.next();
if (child.getName().equals(nameOfElement)) {
searchedElement = child; // on some level it founds it
System.out.println("!!!"); // it's just a marker to see that action happens
//break label;
break;
}
findElement(child, nameOfElement);
}
return searchedElement;
}
Normally, when if condition is performed cycle should stop according to break, but this does not happen. Also I had an idea about adding label. (It' is commented in the code) but it also does not work. Recursion starts and erase variable searchedElement value.
I have found a solution, but it looks ugly and I wonder while upper added code doesn't work. My solution is to add instead of recursive call of findElement(child, nameOfElement); this code:
Element el = findElement(child, nameOfElement);
if (el != null && el.getName().toLowerCase().equals((nameOfElement).toLowerCase())) {
searchedElement = el;
return searchedElement;
}
Please help to find solution!

Try,
public static Element findElement(Element current, String nameOfElement) {
Element searchedElement = null; // this element I want to return
List children = current.getChildren(); // current is a root element passed to method
Iterator iterator = children.iterator();
//label:
while (iterator.hasNext()) {
Element child = (Element)iterator.next();
if (child.getName().equals(nameOfElement)) {
searchedElement = child; // on some level it founds it
System.out.println("!!!"); // it's just a marker to see that action happens
//break label;
break;
}
searchElement = findElement(child, nameOfElement);
if(searchElement != null)
return searchElement;
}
return searchedElement;
}

You just need to return the value of recursive call
public static Element findElement(Element current, String nameOfElement) {
Element searchedElement = null; // this element I want to return
List children = current.getChildren(); // current is a root element passed to method
Iterator iterator = children.iterator();
//label:
while (iterator.hasNext()) {
Element child = (Element)iterator.next();
if (child.getName().equals(nameOfElement)) {
searchedElement = child; // on some level it founds it
System.out.println("!!!"); // it's just a marker to see that action happens
//break label;
break;
}
searchedElement = findElement(child, nameOfElement);//HERE !!!
}
return searchedElement;
}

Related

How to set up a constructor for a Iterator class with a stack?

I need help setting up this constructor for my Iterator class. The directions are as follows:
The constructor should create a new stack and push its node parameter onto it, followed by
all left children accessible from the parameter. Consider a case in which the tree consists
only of left children (essentially a linked list). The node with the highest value (root) would
be pushed first and be on the bottom of the stack, followed by its left child just above it in the
stack, followed by its left child, and so on until the leaf, which would contain the lowest value
in the tree. When popping nodes from the stack, they would contain values from lowest to
highest… an in-order traversal.
I am not sure how to create a new stack with the node in the parameter being a type BSTNode type.
Here is my code:
public static class Iterator<E>
{
private Stack<BSTNode<E>> stack;
public Iterator(BSTNode<E> node)
{
}
public boolean hasNext()
{
if(stack.peek() != null)
{
return true;
}
else
{
return false;
}
}
public E next()
{
stack.pop();
E value;
value = (E) stack.pop();
return value;
}
}
As of right now, just ignore the other two methods, I just need help with the Iterator method. I'll figure those out later. Thank you.
I found out my problem was in a different class and method. I set it up as this and I want to know if this is the correct way of doing it.
The instructions for this method is
to create and return an instance of the static nested Iterator class that will be used to iterate through the elements in the tree. The tree's root should initially be passed to the iterator constructor.
Here is the following code I did for that method:
public Iterator<E> iterator()
{
return new Iterator<>(root);
}
root is the top of the binary search tree. It is in that class as a private variable.
Here's how I set it up.
This is just the public that is above the class. Not inside the class. I just return a new Iterator with root being the top value.
public Iterator<E> iterator()
{
return new Iterator<>(root);
}
Then inside the class below it, I create a new stack and have that stack push the nodes and the nodes to the left of it as long as it isn't null.
public static class Iterator<E>
{
private Stack<BSTNode<E>> stack;
public Iterator(BSTNode<E> node)
{
this.stack = new Stack<>();
while (node != null)
{
stack.push(node);
node = node.left;
}
}
public boolean hasNext()
{
return !stack.isEmpty();
}
public E next()
{
BSTNode<E> goodDays = stack.pop();
E result = goodDays.data;
if (goodDays.right != null)
{
goodDays = goodDays.right;
while (goodDays != null)
{
stack.push(goodDays);
goodDays = goodDays.left;
}
}
return result;
}
}

How can I iterate throughout on list of nested java objects?

I have an object class which is contains a list of itself... Something like this:
public class SearchItemType implements Serializable {
protected List<SearchItemType> childItem;
}
The childItem also can conatain list of child items. My question is, can I iterate over childItems in all levels?
Right now my code looks like this:
public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId, Boolean found) {
SearchItemType element = new SearchItemType();
if (gridResult.getId().equals(selectedRowId)) {
element = gridResult;
found = true;
}
for (SearchItemType child : gridResult.getChildItem()) {
if (child.getId().equals(selectedRowId)) {
element = child;
found = true;
break;
}
}
if (!found) {
for (SearchItemType child : gridResult.getChildItem()) {
element = getElementByOpenedRowID(child, selectedRowId, found);
checkChildID(child, selectedRowId);
if (element != null) break;
}
}
return element;
}
Many thanks.
There is one error: at the start of the method, you set SearchItemType element = new SearchItemType(); but then check for null when you recurse. element will never be null. You can fix this by setting it to null at the start, but I have some suggestions about your code:
Instead of assigning the found value to an element and setting a found flag, just return the object as soon as you find it. At the end of the method return null. This will be much clearer.
Iterating over the children and checking them will currently be executed even if the parent was the one that was searched for. In fact, you can remove this loop entirely, as it is handled by the recursive step below.
Why are you passing found as a parameter? If you pass it true, then there is no point in having it, so if you really need it, just instantiate it in the method.
Make sure to check that gridResult is not null. You could remedy this by making getElementByOpenedRowID a method on SearchItemType, meaning that gridResult does not need to be passed.
Applying these changes will result in:
public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId) {
// stop at null
if (gridResult == null) {
return null;
}
if (gridResult.getId().equals(selectedRowId)) {
return gridResult; // return once found
}
// check all of the children
for (SearchItemType child : gridResult.getChildItem()) {
// do the search again for every child
SearchItemType result = getElementByOpenedRowID(child, selectedRowId);
if (result != null) {
// return once found and sent it all the way to the top
return result;
}
}
return null;
}
You can do this with recursion:
public void iterate(SearchItemType type) {
// Do something with type
for (SearchItemType child in type.childItem) {
iterate(child);
}
}
Yes you can iterate on childItem object at any level as long as childItem is not null and object inside it has non-null values.
In Data structure implementation of LinkedList every node in the LinkedList has Data fields link to other nodes (In case of Java it's reference to other nodes).
It's also called as self referencing objects that means object pointing to object of similar type.
As long as you have non-null values in the list you can iterate at any level.
Data structures in Java are implemented in similar manner.
Have look at Node class in this code snippet:
Linked List implementation using self referencing pointers
You want to iterate through the children recursively as so:
public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId) {
SearchItemType element = null;
if (gridResult == null) return null;
else if (gridResult.getId().equals(selectedRowId)) return gridResult;
else {
for (SearchItemType child : gridResult.getChildItem()) {
element = getElementByOpenedRowID(child, selectedRowId);
if (element != null) break;
}
}
return element;
}

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;
}

Delete method doesn't delete a node with specific name

Hi guys i am trying to delete a node that has a specific name. but apparently doesn't delete the node it just prints out everything. The node that contains the name doesn't get deleted. I wrote my linked list and everything works except deleting a node that has a specific name. Below is my method for deleting a specific name:
public void remove(String name)
{
if(!this.isEmpty())
{
LinkedList current = first;
//LinkedList prev = null;
while(current!=null)
{
//prev = current;
if(current.name.equals(name))
{
current = current.getNext();
count--;
break;
}
current=current.getNext();
}
}
else
{
System.out.println("Cannot search an empty list");
}
}
main method:
public static void main(String[] args) {
// TODO Auto-generated method stub
Link a = new Link();
a.addEnd("Tom"); //adds at the end of list
a.addEnd("Joe");
a.addEnd("Gary");
a.add("Kim"); //adds at the beginning of the list
a.addIndex("Nene", 1); //adds to an index position.
a.remove("Kim"); //calls the method to remove the name kim but doesn't delete it.still displays kim on the console.
a.display();
}
}
I think a very minor adjustment will get this working. I'm making the assumption that you're extending the built-in Java LinkedList:
In your conditional:
if(!this.isEmpty())
{
LinkedList current = first;
//LinkedList prev = null;
while(current!=null)
{
//prev = current;
if(current.name.equals(name))
{
// Right here you need to do a this.remove(current.getId)
current = current.getNext();
count--;
break;
}
current=current.getNext();
}
}
You're decrementing the count, but you're not actually removing the element from the list. Java's built in LinkedList has a remove by ID method: LinkedList.remove. Since you've got the element that matches the name, then you should be able to pass the index of that element's ID to the remove method.
If you're not doing this as an extension of the existing method then I would recommend using a look ahead. Know your current and your next. That way you can follow this logic (pardon my pseudocode):
If next matches, do next.getNext()
If next.getNext() returns null,
then pop the last value off the list (current.setNext(null))
Else
do current.setNext(next.getNext())

Java Linked List search and delete method

I have a project for computer science class and have everything done except for one method. The delete method. Basically I am making a linked list from user input and I need to be able to delete all nodes (which is done) and delete a single specified node. So I need to search through the list of nodes find the one to delete and delete it. Anything that can help is appreciated. If you have a solution please offer an explanation as I am trying to learn and just solve the problem.
I'm not going to give you the GUI because I don't think it is necessary but here is the node class.
public class MagazineList {
private MagazineNode list;
public MagazineList(){
list = null;
}
public void add(Magazine mag){
MagazineNode node = new MagazineNode(mag);
MagazineNode current;
if(list == null) {
list = node;
}
else {
current = list;
while(current.next != null)
current = current.next;
current.next = node;
}
}
public void insert(Magazine mag) {
MagazineNode node = new MagazineNode (mag);
// make the new first node point to the current root
node.next=list;
// update the root to the new first node
list=node;
}
public void deleteAll() {
if(list == null) {
}
else {
list = null;
}
}
public void delete(Magazine mag) {
//Delete Method Goes Here
}
public String toString(){
String result = " ";
MagazineNode current = list;
while (current != null){
result += current.magazine + "\n";
current = current.next;
}
return result;
}
private class MagazineNode {
public Magazine magazine;
public MagazineNode next;
public MagazineNode(Magazine mag){
magazine = mag;
next = null;
}
}
}
UPDATE
Here is the method I put together and it goes through the first part into the while loop and never recognizes the same item in the list. I used the exact same thing for the input and delete methods yet it will not recognize it. Any help is appreciated.
public void delete (Magazine mag) {
MagazineNode current = list;
MagazineNode before;
before = current;
if(current.equals(mag)){
before.next = current;
System.out.println("Hello");
}
while ((current = current.next)!= null){
before = current.next;
System.out.println("Hello Red");
if(current.equals(mag)){
current = before;
System.out.println("Hello Blue");
}
}
}
Without spoon feeding you the answer. deletion is a bit like removing one link of a chain - you cut out the link and join up the two (new) ends.
So, deleting "B" would mean changing
A --> B --> C --> D
to this
A --> C --> D
In pseudo code, the algorithm would be:
start the algorithm with the first node
check if it is the one you want to delete
if not, go to the next node and check again (go back to the previous step)
if so, make the next node of the previous node the next node of this node
remove the reference from this node to the next node
public void delete (Magazine mag) {
MagazineNode current = this.list;
MagazineNode before;
//if is the first element
if (current.equals(mag)) {
this.list = current.next;
return; //ending the method
}
before = current;
//while there are elements in the list
while ((current = current.next) != null) {
//if is the current element
if (current.equals(mag)) {
before.next = current.next;
return; //endind the method
}
before = current;
}
//it isnt in the list
}
the comments should explains whats happening
All you need to do is search through the list, keeping track of where you are. When the node you want to delete is in front of you, set the current node's "next" to the one after the one you want to delete:
for(Node current = list; current.next() != null; current = current.next()){
if(current.next().magazine().equals(toDelete)) current.setNext(current.next().next());
}
Something like that.
Hope that helps!

Categories

Resources