Using wrapper class instead of static variables - java

This is my first question ever at StackOverFlow:
I am studying to interviews with the help of "Cracking the code interview" (5th Edition) book,
and I was solving the next problem:
Implement a function to check if a binary tree is a binary search tree (Q 4.5 pg 86).
Before we move on, I would like just to remind you the difference between a Binary search tree to a simple Binary tree:
A Binary search tree imposes the condition that for all nodes, the left children are less than or equal to the current node, which is less than all the right nodes.
So one of the solution the book offers is to scan the tree with In-Order traversal and on the fly to check if every node we visit is greater then the last one, and it assumes the tree can't have a duplicate values:
public static int last_printed = Integer.MIN_VALUE;
public static boolean checkBST(TreeNode n) {
if(n == null) return true;
// Check / recurse left
if (!checkBST(n.left)) return false;
// Check current
if (n.data <= last_printed) return false;
last_printed = n.data;
// Check / recurse right
if (!checkBST(n.right)) return false;
return true; // All good!
}
Now, up here everything is good, but then the book quotes :
If you don't like the use of static variables, then you can tweak this code to use a wrapper class for the integer, as shown below:
Class WrapInt {
public int value;
}
After reading on wrapper class all over here and in other websites I just couldn't come to the conclusion, why and how should I use the wrapper class here instead of the static variable?

This is a mechanism whereby you can create an instance of WrapInt, and pass it around. You then expose the value only to code that should know about it, instead of a public static non-final variable that can be accessed and changed from anywhere.
The reason you have the wrapper class is because Java primitives are pass-by-value; passing around an int and then updating it wouldn't propagate the change through the rest of your system.
This would look like this:
public static boolean checkBST(TreeNode n) {
WrapInt counter = new WrapInt();
return checkBST(n, counter);
}
public static boolean checkBST(TreeNode n, WrapInt counter) {
if(n == null) return true;
// Check / recurse left
if (!checkBST(n.left, counter)) return false;
// Check current
if (n.data <= counter.value) return false;
counter.value = n.data;
// Check / recurse right
if (!checkBST(n.right, counter)) return false;
return true; // All good!
}

Here you go:
public static boolean checkBST(TreeNode n) {
WrapInt i = new WrapInt();
i.value = INTEGER.MIN_VALUE;
doCheckBST(n, i);
}
private static boolean doCheckBST(TreeNode n, WrapInt last_printed) {
if(n == null) return true;
// Check / recurse left
if (!checkBST(n.left, last_printed)) return false;
// Check current
if (n.data <= last_printed.value) return false;
last_printed.value = n.data;
// Check / recurse right
if (!checkBST(n.right, last_printed)) return false;
return true; // All good!
}

If there is the possibility that there will run 2+ sorts at the same time. The static will be used for both sortings. Both sortings have access to the same static value.
//thread 1
Sorting A = new Sorting(5,9,8);
A.sort();
//thread 2
Sorting B = new Sorting(999,100,7);
B.sort();
We cant predict which/how the thread is processed.
So this could end up in
A.checkBST(5) // last_printed = 5
B.checkBST(999) // last_printed = ??
B.checkBST(100) // last_printed = ??
A.checkBST(9) // last_printed = ??
...
...
If every sort instance has his own last_printed, you won't have synchronisation issues.

I think this is more formal way how to avoid of public static context property (e.g for thread safety), which is not optimal approach in object programming. But there are standard Primitive wrapper classes as: https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html
which can be used instead of new classes. Generally Wrapper pattern can be more general than your example: What is a wrapper class?

The problem with static variable is that another class/method or something can modify it and it will break your code.
Can you make it like that:
Class WrapInt {
public int value=Integer.MIN_VALUE;
}
public static boolean checkBST(TreeNode n,WrapInt lastPrinted) {
if(n == null) return true;
// Check / recurse left
if (!checkBST(n.left,lastPrinted)) return false;
// Check current
if (n.data <= lastPrinted.value) return false;
lastPrinted.value = n.data;
// Check / recurse right
if (!checkBST(n.right,lastPrinted)) return false;
return true; // All good!
}

Related

Having trouble sorting leaves in ascending order for binary tree

So the original problem is Write the method chechkLeaves(), which should return true if the leaves of the tree are sorted in increasing order and false otherwise. You can assume that data for all internal nodes are null. You will find it useful to define additional recursive helper methods for this problem. 
Edit: My code is working now, but how can I modify the code so that I the val is passed in as a parameter rather than global variable?
static int val = 0;
static public boolean checkLeaves(Node root) {
// int val = 0;
if(root.data != 0 ) {
if(root.data > val) {
val = root.data;
return true;
} else {
return false;
}
} else {
return checkLeaves(root.left) && checkLeaves(root.right);
}
}
There isn't really a way for you to be able to do this traversal of the leaves with comparison without a global variable. This is something that can be accomplished with passing-by-reference, but Java doesn't have such a feature. So, you have two options:
Option 1) Stick with this static variable.
Option 2) Make val a parameter as an array, as such:
private static public boolean checkLeaves(Node root, int[] val) {
if (root.data != 0) {
if (root.data > val[0]) {
val[0] = root.data;
return true;
} else {
return false;
}
} else {
return checkLeaves(root.left, val) && checkLeaves(root.right, val);
}
}
And to call it:
checkLeaves(root, new int[] { Integer.MIN_VALUE });
By making it an array, you can emulate that "pass by reference" behavior. That is, updating the original value of the variable by having a reference to the original value. Everything in Java is pass-by-value, so the value of the variable is passed to the parameter, not the reference to it.
Note
I suggest you name your variables a little more descriptive. For example, instead of val, you could name it previousLeafValue or something.
Also, a good practice to follow is making everything as "private" as possible. In option 2 you can see my code have the method with a private access modifier. The same is true for your static variable. Make it a habit to make things private by habit, then expand their modifiers as needed.

Is there a better way of writing this loop?

I need to check whether at least 1 item in a list has X, Y, and Z (not all at the same time). e.g. item 1 has x, and item 2 has y and z.
I thought it'd be better to do this without creating multiple loops and just checking for one of them, but instead store a variable and then check it so it can't be set to false again once true.
Seems like I'm probably missing a better way to do this, so is there one?
Thanks
boolean hasX = false;
boolean hasY = false;
boolean hasZ = false;
for (ItemType item : Items) {
if (!hasX) { hasX = DoesHaveX(item); }
if (!hasY) { hasY = DoesHaveY(item); }
if (!hasZ) { hasZ = DoesHaveZ(item); }
}
If you are going to stick to a JVM below 1.8 then your code is just fine!
Maybe you could skip few operations like breaking the loop once you found a match for the three booleans, and checking only those which are not found any yet.
for (ItemType item : items) {
hasX = hasX || doesHaveX(item);
hasY = hasY || doesHaveY(item);
hasZ = hasZ || doesHaveZ(item);
if (hasX && hasY && hasZ) {
break;
}
}
If you are just fine to use streams maybe it's better to initialize each of the variables at it's creation like so:
boolean hasX = items.stream().anyMatch(this::doesHaveX); // goes trough the elements until a match is found.
boolean hasY = items.stream().anyMatch(this::doesHaveY); // goes trough the elements until a match is found.
boolean hasZ = items.stream().anyMatch(this::doesHaveZ); // goes trough the elements until a match is found.
Here is an extendable approach that uses an enum so you never have to touch the logic of hasOneOfAll again. You just have to extend the given enum.
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
class StackOverflowQuestion56902308Scratch {
class ItemType {
boolean x;
boolean y;
boolean z;
}
enum ItemTypeCheck implements Predicate<ItemType> {
HASX() {
#Override
public boolean test(ItemType itemType) {
//TODO: implement me
return itemType.x;
}
},
HASY() {
#Override
public boolean test(ItemType itemType) {
//TODO: implement me
return itemType.y;
}
},
HASZ() {
#Override
public boolean test(ItemType itemType) {
//TODO: implement me
return itemType.z;
}
}
}
public static boolean hasOneOfAll(List<ItemType> itemTypes) {
Map<ItemTypeCheck, Boolean> result = new EnumMap<>(ItemTypeCheck.class);
for (ItemType itemType : itemTypes) {
for (ItemTypeCheck check : ItemTypeCheck.values()) {
result.merge(check, check.test(itemType), Boolean::logicalOr);
}
}
return result.values().stream().allMatch(hadOne -> hadOne);
}
}
Personally I am not sure if this is too overengineered but it alleviates the pain of manually adjusting the function if another check is added in the future.
A Stream map/reduce version of the loop for fun. Not sure if it is better to be honest. But at least we get rid of all the variables
map each item to a list of 3 booleans (one for each attribute x,y,z)
reduce the whole list into a list of 3 booleans (one for each attribute x,y,z) checking if any of the items has each value
check that all the elements of the the resulting list are true.
boolean allGood = items.stream()
.map(i -> Arrays.asList(doesHaveX(i), doesHaveY(i), doesHaveZ(i)))
.reduce(Arrays.asList(false, false, false),
(acc, elem) -> Arrays.asList(acc.get(0) || elem.get(0),
acc.get(1) || elem.get(1),
acc.get(2) || elem.get(2)))
.stream()
.allMatch(Boolean::booleanValue);
Just to add a BitSet variant too, and under the assumption that checking has... is a semi-expensive operation:
private static final int xBit = 0;
private static final int yBit = 1;
private static final int zBit = 2;
public static boolean hasAll(final Collection<ItemType> items) {
if (items.isEmpty()) return false;
final BitSet bits = new BitSet(3);
for (final ItemType item : items) {
// Check if bit is already set to avoid
// needless `has*` evaluation
if (!bits.get(xBit) && hasX(item)) bits.set(xBit);
if (!bits.get(yBit) && hasY(item)) bits.set(yBit);
if (!bits.get(zBit) && hasZ(item)) bits.set(zBit);
// You could repeat this INSIDE all of the 'if's
// above to potentially avoid computing bits.get
// but I'd sacrifice that for the slightly improved
// readability.
if (bits.cardinality() == 3) return true;
}
return false;
}
I can't tell you if this is faster or anything, as that depends on your has* implementations, amongst other things. But it avoids most recomputations whereever possible.

Finding the maximum value of a linked list recursively

I need to write a Java method called findMax within a class called Node, which has two instance variables: int value and Node next. The method takes no parameters, and must return the greatest value of a linked list. Within the context of the program, the method will always be called by the first Node of a linked list (except for the recursive calls). I was struggling to complete the method when I accidentally found a working solution:
public int findMax(){
int max = value;
if(next == null){
return max;
}
else{
if(max <= next.findMax()){
max = next.value;
}
else return max;
}
return next.findMax();
}
This method properly returned the largest value of each linked list I tested it for. However, since I found this solution by trying random arrangements of code, I don't really feel like I understand what's going on here. Can anyone explain to me how/why this works? Also, if there is a more efficient solution, how would it be implemented?
You can imagine a linked list looking something like this:
val1 -> val2 -> val3 -> null
Recursion works on the principle that eventually, the input you pass into the function can be handled without recursing further. In your case, node.findMax() can be handled if the next pointer is null. That is, the max of a linked list of size 1 is simply the value (base case of the recursion), the max of any other linked list is the max of the value of that node or the max of the remaining elements.
ie) for the Node n3 with value val3, n3.findMax() simply returns the value
For any other node n, n.findMax() returns the maximum of the node's value or n.next.findMax()
The way this looks in the example at the start is:
n1.findMax()
= Max(n1.value, n2.findMax())
= Max(val1, Max(n2.value, n3.findMax())
= Max(val1, Max(val2, n3.value)) // Since n3.next == null
= Max(val1, Max(val2, val3))
which is simply the maximum over the whole list
Edit: Based on the discussion above, although what you said might work, there is a simpler way of writing the program:
int findMax() {
if (this.next == null) {
return this.value;
} else {
return Math.max(this.value, this.next.findMax());
}
}
Edit 2: A break down of why your code works (and why it's bad):
public int findMax(){
// This variable doesn't serve much purpose
int max = value;
if(next == null){
return max;
}
else{
// This if condition simply prevents us from following
// the else block below but the stuff inside does nothing.
if(max <= next.findMax()){
// max is never used again if you are here.
max = next.value;
}
else return max;
}
// We now compute findMax() again, leading to serious inefficiency
return next.findMax();
}
Why is this inefficient? Because each call to findMax() on a node makes two subsequent calls to findMax() on the next node. Each of those calls will generate two more calls, etc.
The way to fix this up is by storing the result of next.findMax() like so:
public int findMax() {
if (next == null) {
return value;
}
else {
int maxOfRest = next.findMax();
if(value <= maxOfRest) {
return maxOfRest;
}
else return value;
}
}

Recursive implementation of a method

I'm new to Java and still trying to wrap my head around recursion.The function below returns true at the very first intersection between the two sorted lists list x and list y.
public static boolean checkIntersection(List<Integer> x, List<Integer> y) {
int i = 0;
int j = 0;
while (i < x.size() && j < y.size()) {
if (x.get(i).equals(y.get(j))) {
return true;
} else if (x.get(i) < y.get(j)) {
i++;
} else {
j++;
}
}
return false;
}
Now I've been trying to implement it using recursion instead, and I know that there should be a base case which is an empty list in this case and then try to reduce the list by excluding one element at a time and feed it back to the same recursive function, but I can't work out how to check for intersection as I pass the rest of the list over and over.
public static boolean recursiveChecking(List<Integer> x,List<Integer> y) {
if(x.size() == 0){
return false;
}
else {
return recursiveChecking(x.subList(1, x.size()-1), y);
}
}
Any help would be highly appreciated. Thank you.
General approach to making something recursive is to think of two things:
When can I produce an answer trivially? - An answer to this question lets you code the base case. In your situation, you can produce the answer trivially when at least one of two lists is empty (the result would be false) or the initial elements of both non-empty lists are the same (the result would be true)
How do I reduce the problem when the answer is non-trivial? - An answer to this question lets you decide how to make your recursive call. In your case you could, for example, remove the initial element of one of the lists before making the recursive call*, or pass ListIterator<Integer> in place of List<Integer> for a non-destructive solution.
*Of course in this case you need to take care of either adding your numbers back after the call, or make a copy of two lists before starting the recursive chain.
As the lists are ordered, your recursion should remove the first element of the list with the smaller first value. Then you have to return true, if both lists start with the same number and false if any of the lists is empty. Otherwise you keep removing elements. This would look something like this (This code is untested):
public static boolean recursiveChecking(List<Integer> x,List<Integer> y) {
if(x.size() == 0 || y.size() == 0){
return false;
} else if (x.get(0).equals(y.get(0))) {
return true;
} else {
if (x.get(0) < y.get(0)) {
return recursiveChecking(x.subList(1, x.size()-1), y);
} else {
return recursiveChecking(x, y.subList(1, y.size()-1));
}
}
}

Turning a for loop to recursive method for prime numbers

I need to convert the code below to a recursive method without using global variables and using only one parameter.I Searched the topics already there is no code with one parameter and doesnt use the global variables.
public boolean isPrime(int x){
for(int i=2;i<x;i++)
if(x%i==0) return false ;
return true;
}
Ok, as for your requirements:
Without using global variables.
Using only one parameter.
And, based on:
it come up in one of my university exams
There a couple of aspects to take into account:
If you pass an instance of a Class you are passing only one variable, and as Classes can have multiple variables inside...
They do not state if you can call multiple functions inside, so, again, this is a hint or clue, of what can you do. So, two solutions for you:
Solution 1 (Using Classes)
class RecursVar {
int x;
int i = 2;
RecursVar(int x) {
this.x = x;
}
}
public boolean isPrimeRecurs(int x){
return isPrime(new RecursVar(x));
}
boolean isPrime(RecursVar recursVar) {
if(recursVar.x % recursVar.i == 0)
return false;
if (++recursVar.i >= recursVar.x)
return true;
return isPrime(recursVar);
}
Solution 2 (Cleaner approach without using Classes but based in that the function that can have only one parameter is isPrime )
boolean isPrime(int x) {
return checkForPrime(x, 2);
}
boolean checkForPrime(int x, int i) {
if (i >= x) return true;
if (x % i == 0) return false;
return checkForPrime(x, ++i);
}
Again, this solutions are based on that many exams require a little creativity and maybe that was the aim of this case.
This cases should not be used in production, they are slow and
prune to make honor to this site (StackOverFlow) with a sweet
java.lang.StackOverflowError
It's an interesting problem.
If you can use java 8, you can solve the problem as followed (note that the case isPrime(2) needs to be checked with an additional if condition):
package test;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
System.out.println(isPrime(13));
}
private static Function<Integer, Boolean> fun;
public static boolean isPrime(int x) {
fun = i -> {
if (i > 2) return (x%i != 0) && fun.apply(i-1);
else return (x%i != 0);
};
return fun.apply(x-1);
}
}
One of my schoolmates' topic accually recieve a solution here it is if you interested its quite brilliant
https://stackoverflow.com/questions/35660562/finding-prime-numbers-recursively-with-using-only-one-parameter?noredirect=1#comment59001671_35660562

Categories

Resources