Recursion not working when called into another class - java

I wrote a recursive method which searches through a BST, compares the argument with the string property in the node, and returns the int property from that node if the strings match. The method works when it's called in it's own class, however, when I call it into a different class, it doesn't work anymore. So basically, the private part of the method works, its just the public part that's messing me up.
public int boka(String ime) {
int bobo=boka(this.root,ime);
return bobo;
}
private int boka(Node curr_root,String ime){
if(curr_root==null){
return -1;
}
boka(curr_root.left,ime);
if(curr_root.info.ime.equalsIgnoreCase(ime)) {
return curr_root.info.pobjede;
}
boka(curr_root.right,ime);
return -1;
}
So basically, the private part works, however, when I call the recursion in another class using the public, it always returns -1.
In the other class, I'm doing this:
public static void main(String[] args) {
// TODO Auto-generated method stub
BinTree bt = new BinTree();
int a = bt.boka("Djole");
I omitted the actual Node making and inserting, since I don't think that's relevant.

Your search will always return -1 because you haven't properly implemented the search. I don't know why it's working when you run it in "it's own class" but you need to return the value of the recursive call; otherwise, you are just returning -1 when the recursion is complete.
You can adjust your algorithm to this, and get it to work:
private int boka(Node curr_root,String ime){
if(curr_root.left != null) return boka(curr_root.left,ime);
if(curr_root.info.ime.equalsIgnoreCase(ime)) return curr_root.info.pobjede;
if(curr_root.right != null) return boka(curr_root.right,ime);
return -1;
}

That does not seem like searching in a Binary Search Tree (or what else BST means?), it is more like an in-order traverse of an arbitrary binary tree.
You can make it working, just do not disregard the return values in the recursion:
private int boka(Node curr_root,String ime){
if(curr_root==null) {
return -1;
}
int ret=boka(curr_root.left,ime);
if(ret!=-1) {
return ret
}
if(curr_root.info.ime.equalsIgnoreCase(ime)) {
return curr_root.info.pobjede;
}
return boka(curr_root.right,ime);
}

Related

How to write the depth() method without the Node inside the parameter?

There is an assignment where we have to modify the Binary Tree with the following methods. I was able to write all the methods to work, including the depth() method. However, as I read the question carefully I noticed that I wrote this method with a node inside the parameters instead of a variable (in this case its int key).
Here is my code:
public int getDepth(Node node) {
if (node == null) {
return 0;
} else {
int leftSubtreeDepth = getDepth(node.leftChild);
int rightSubtreeDepth = getDepth(node.rightChild);
if (leftSubtreeDepth > rightSubtreeDepth) {
return (leftSubtreeDepth + 1);
} else {
return (rightSubtreeDepth + 1);
}
}
}
The output is correct when I used this code. However, now that I know that I have to write the depth method with an int key variable (aka. public int getDepth(int key) ), is there anything I can do to change this code up? I hope it's just a small change/fix since it took me a while to write this code.

Removing specific element from ArrayList

I need help with removing just added element from the arrayList.
I have a private static ArrayList<Position> positions = new ArrayList<>() to which I'm adding objects of the class Position with parameters name, quantity, and price.
Than I have a method adding objects to the list, and in case if the same product is added for the second time, it is supposed to add the quantity to the first object of that name and remove that second one.
So far I have this method:
public void addPosition(Position p) {
for (Position poz: positions) {
if (poz.getname().equals(p.getname())) {
poz.setquantity(poz.getquantity() + p.getquantity());
}
} positions.add(p);
}
Adding quantities works just fine, but I've got problem with removing the element with recurring name.
Please help.
You shouldn't add duplicate items and then remove them. Just declare a method which handles adding items correctly; that is, it adds the item if it does not exist, and it updates the quantity if it does exist.
It should look like this:
public void addPosition(Position addition) {
//flag to track whether the new item exists in the list
boolean itemExists = false;
//go through the list looking for an item with the passed name to update
for (Position existing : positions) {
if (existing.getName().equals(addition.getName())) {
existing.setQuantity(existing.getQuantity() + addition.getQuantity());
itemExists = true;
}
}
//if no matching item was found, add the new item
if (!itemExists) {
positions.add(addition);
}
}
The above should work. If you care about performance, it might be better to use a HashMap so you can look up the Position by name instead of looping through the whole list each time.
If you are interested to know other data Structure , i want suggest you HashSet , by default it will not insert duplicates for primitive objects .
In your case the only thing you need to do to your Position class , is to add
equals and hashCode methods . As getters and setters Eclipse for example will create by him self .
hashCode()
As you know this method provides the has code of an object. Basically the default implementation of hashCode() provided by Object is derived by mapping the memory address to an integer value. If look into the source of Object class , you will find the following code for the hashCode. public native int hashCode(); It indicates that hashCode is the native implementation which provides the memory address to a certain extent. However it is possible to override the hashCode method in your implementation class.
equals()
This particular method is used to make equal comparison between two objects. There are two types of comparisons in Java. One is using “= =” operator and another is “equals()”. I hope that you know the difference between this two. More specifically the “.equals()” refers to equivalence relations. So in broad sense you say that two objects are equivalent they satisfy the “equals()” condition. If you look into the source code of Object class you will find the following code for the equals() method.
Here a complete working example ( you can modify your class following this cose)
import java.util.HashSet;
public class Zhashset{
private int num;
public Zhashset(){
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + num;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Zhashset other = (Zhashset) obj;
if (num != other.num)
return false;
return true;
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<Zhashset> hs = new HashSet<Zhashset>();
hs.add(new Zhashset());
hs.add(new Zhashset());
for(Zhashset item : hs)
System.out.println(item.getNum());
}
}
Output will be : 0 written only once.

Homemade Stack Equals method

For my data structures class, we have to create our own Stack data type and the implementation for it as a project. The problem I'm running into is when the professor asked us to implement an equals(Object object) method. Heres what I have so far...
package stack;
import list.*;
public class Stack <E>
implements StackADT<E>//the interface
{
List <E> values;
public Stack()
{
values = new ArrayList<E>();
}
public E push(E value)
{
values.add(value);
return value;
}
public E pop()
{
return values.remove(values.size()-1);
}
public E peek()
{
return values.get(values.size()-1);
}
/** #return true only if this Stack is empty */
public boolean isEmpty()
{
return (values.size()==0);
}
/** Clear this stack, to make it an empty stack */
public void clear()
{
for (int i = 0; i < values.size()-1; i++)
{
pop();
}
}
public String toString()
{
String result = "[";
for (int i = 0; i<values.size(); i++)
{
if (i == values.size()-1)
{
result = result + values.get(i);
}
else
{
result = result + values.get(i) +",";
}
}
result = result + "]";
return result;
}
public boolean equals (Object object)
{
if (!(object instanceof StackADT))
{
return false;
}
StackADT <E> otherStack = new Stack<E>();
for(Object o: object)//heres where i run into trouble
{
otherStack.push(o);
}
for (int i=0;i<values.size()-1;i++)
{
if (!(values.get(i).equals(otherStack.pop())))
{
return false;
}
}
return true;
}
}
Our Stack is pretty much an ArrayList which we also built in our class. the problem is, I cant add the Object object into a stack because its not something thats iteratable(?able to be iterated over). Is there a better way to do this? I would think a get() would work, since the Stack I create is an ArrayList, but whenever I use get() on otherStack, it can't find the method. I had a temporary solution when I tried casting object as a stack(I hope im using the right terminology). It looked something like this
Stack otherStack = (Stack) object;
for (int i=0;i<values.size()-1;i++)
{
if (!(values.get(i).equals(otherStack.pop())))
{
return false;
}
}
return true;
}
this seemed to work, but when pop() was called on otherStack, the values in the original list(the one that becomes otherStack) that was passed into the equals() method we're also popped from the original list, leading to an incorrect result. Is there a better way to do this without adding in any other methods? I'm trying to stick as close to the formula set up by my professor as possible, so I dont want to add any extra fields or methods.
any and all help is appreciated
An equals method is not supposed to create anything, not even a temporary object. Rather than creating a new otherStack, cast the object that you have checked to be StackADT, like this:
// This should be the first line of any equals() implementation:
if (object == this) {
return true;
}
// You've got this part right: you need to check the other object's type
if (!(object instanceof StackADT)) {
return false;
}
// Now that you know the type, cast the other object to StackADT<E>
StackADT<E> otherStack = (StackADT<E>)object;
// The next step is to check the sizes:
if (values.size() != otherStack.values.size()) {
return false;
}
// Finally, go through the individual elements in a loop
In the loop that follows, do not pop the other stack. Do not do anything that can modify it. Simply go through the underlying storage (i.e. values), and check elements one by one.
Don't forget to override hashCode as well: you need to do it every time when you override equals for the object to fulfill the contract specified by java.lang.Object.

How to change one Boolean based on values found in ArrayList?

I am trying to make a deductive Algorithm for solving a Sudoku puzzle. My Board is made up of 81 Nodes in an ArrayList.
- Each Node has a boolean Value
I want my algorithm (called CRME) to be continue to try and solve the puzzle if it finds that at least one of the nodes has it's boolean value (hasChanged) equal to true but I am unsure how to do this. canChange is also a global variable in the class this method is contained in.
public void CRME() {
canChange = true;
while (canChange == true) {
for (Node node : cells) {
scanColumn(node);
scanRow(node);
scanMiniGrid(node);
}
}
}
public void scanRow(Node n){
for(Node node : cells){
int arraySize = node.posVals.size();
ArrayList<Integer> toRemove = new ArrayList<Integer>();
if(node.get_ROW_ID() == n.get_ROW_ID()){
toRemove.add(node.getValue());
}
n.posVals.removeAll(toRemove);
if(arraySize < node.posVals.size()){
node.hasChanged = true;
}
}
}
This is the scanRow method, the two other similarly named methods are the same but with the obvious syntax changed, such as node.get_ROW_ID(); would be node.get_COL_ID();.
I assume you have a static variable
static boolean hasChanged; // in the Node class
so you can use:
node.hasChanged = true;
or you can create hasChange method to set the variable like so
boolean hasChanged;
public void hasChanged(boolean val){
this.hasChanged = val;
}
and use in the loop, like so:
hasChanged(true); or hasChanged(false);
Not saying your approach is best, but if you are trying to simply continue while one of hasChanged is true for any of your nodes, the following will suffice:
public void CRME()
{
goOn = false;
for (Node node : yourArrayListOfNodes)
{
if (node.hasChanged)
{
goOn = true;
break;
}
}
if (goOn)
{
//Insert Whatever code you want to run after the check
//.........................................
//Use recursion to repeat process
//Note recursive call will only take place if goOn is true
CRME()
}
}
This seems like what you want to do, just note that if your logic is incorrect, you can get a StackOverflowError, since you would keep making recursive calls.

Search an attribute inside a Vector on Java

I've a Vector of objects, and have to search inside for a random attribute of those objects (For example, a Plane class, a Vector containing Plane; and I've to search sometimes for destination, and others to pilotName).
I know I can traverse the Vector using an Iterator, but I've got stuck at how do I change the comparison made between a String and the attribute on the object. I thought of using switch, but a another opinion would be cool.
Update 1:
The code I've written is something like this (Java n00b alert!):
public int search(String whatSearch, String query){
int place = -1;
boolean found = false;
for ( Iterator<Plane> iteraPlane = this.planes.iterator(); iteraPlane.hasNext() && found == false; ) {
Plane temp = (Plane) iteraPlane.next();
/* Here is where I have to search for one of many attributes (delimited by whatSearch */
}
return place;
}
Seems I've to stick to linear search (and that's a price I've able to pay). Anyway, I was thinking if Java had something like variable variable name (ouch!)
I assume that your problem is that you want to have a method that searches for a result based on some property of the collection type. Java is weak on this because it is best expressed in a language which has closures. What you need is something like:
public interface Predicate<T> {
public boolean evaluate(T t);
}
And then your search method looks like:
public static <T> T findFirst(List<T> l, Predicate<T> p) { //use List, not Vector
for (T t : l) { if (p.evaluate(t)) return t; }
return null;
}
Then anyone can use this general-purpose search method. For example, to search for an number in a vector of Integers:
List<Integer> is = ...
findFirst(is, new Predicate<Integer> {
public boolean evaluate(Integer i) { return i % 2 == 0; }
});
But you could implement the predicate in any way you want; for any arbitrary search
Use Collections.binarySearch and provide a Comparator.
EDIT: This assumes that the Vector is sorted. Otherwise, one has to do a linear search.
the equals() method is the best option. For these iterations you could do something like this:
for (Plane plane: planes) {
if ("JFK".equals(plane.getDestination())) {
// do your work in here;
}
}
or you could override the equals() method within Plane to see if the String passed in matches your destination (or pilot). this will allow you to use the indexOf(Object) and indexOf(Object, index) methods on Vector to return you the index(es) of the object(s). Once you have that, you could use Vector.get(index) to return to Object for you.
in Plane.java:
public boolean equals(Object o) {
return o.equals(getDestination()) ||
o.equals(getPilot()) ||
super.equals(o);
}
there is more work to be done with this option, as you will need to override hashCode() as well (see documentation).
See #oxbow_lakes above -- I think what you want isn't to pass a String as whatSearch, it's to pass a little snippet of code that knows how to get the property you're interested in. For a less general version:
public static interface PlaneMatcher {
boolean matches(Plane plane, String query);
}
public int search(PlaneMatcher matcher, String query){
int place = -1;
boolean found = false;
for ( Iterator<Plane> iteraPlane = this.planes.iterator(); iteraPlane.hasNext() && found == false; ) {
Plane temp = (Plane) iteraPlane.next();
if (matcher.matches(temp, query) {
found = true;
}
place++;
}
return place;
}
...
// example
int pilotNameIndex = search(new PlaneMatcher() {
boolean matches(Plane plane, String query) {
// note: assumes query non-null; you probably want to check that earlier
return query.equals(plane.getPilotName());
}
}, "Orville Wright");
(By the way, if it's the index you're interested in rather than the Plane itself, I wouldn't bother with an Iterator -- just use an old-fashioned for (int i = 0; i < planes.size(); i++) loop, and when you have a match, return i.)
Now, the tricky bit here is if what you have to search for is really identified by arbitrary strings at run-time. If that's the case, I can suggest two alternatives:
Don't store these values as object fields -- plane.pilotName, plane.destination -- at all. Just have a Map<String, String> (or better yet, a Map<Field, String> where Field is an Enum of all the valid fields) called something like plane.metadata.
Store them as object fields, but prepopulate a map from the field names to PlaneMatcher instances as described above.
For instance:
private static final Map<String, PlaneMatcher> MATCHERS = Collections.unmodifiableMap(new HashMap<String, PlaneMatcher>() {{
put("pilotName", new PlaneMatcher() {
boolean matches(Plane plane, String query) {
return query.equals(plane.getPilotName());
});
...
put("destination", new PlaneMatcher() {
boolean matches(Plane plane, String query) {
return query.equals(plane.getDestination());
});
}}
...
public int search(String whatSearch, String query){
PlaneMatcher matcher = MATCHERS.get(whatSearch);
int place = -1;
boolean found = false;
for ( Iterator<Plane> iteraPlane = this.planes.iterator(); iteraPlane.hasNext() && found == false; ) {
Plane temp = (Plane) iteraPlane.next();
if (matcher.matches(temp, query) {
found = true;
}
place++;
}
return place;
}
Oh, and you might be tempted to use reflection. Don't. :)
A simple way is to pass a comparison function to your search routine. Or, if you need more speed, use generics.

Categories