I'm wondering how to accomplish this:
Compare two Stack objects
Do this recursively
After the method that
does this is complete, the Stacks remain as they were to begin with
(i.e. same order, same items).
Only the push, pop and isEmpty methods for Stack is available.
I'm looking more for theoretical help than coding help, but any insight would be appreciated.
Two stacks are identical if their top level elements are identical, and the remaining stacks are identical (namely, the recursive condition).
Now, think what to do just before returning from the method call, in order to leave the stacks the same way they where given at the invocation time.
---EDIT---
The working Java code (derived from Markus A. solution, but with an interesting use of "finally" and with generics):
static <T> boolean compareStacks(Stack<T> a, Stack<T> b) {
if (a.isEmpty() != b.isEmpty()) return false;
if (a.isEmpty() && b.isEmpty()) return true;
T element_a = a.pop();
T element_b = b.pop();
try {
if (((element_a==null) && (element_b!=null)) || (!element_a.equals(element_b)))
return false;
return compareStacks(a, b);
} finally { // restore elements
a.push(element_a);
b.push(element_b);
}
}
In pseudo-code, you could do something like this:
boolean compareStacks(a, b) {
if (a.isEmpty() != b.isEmpty()) return false; // check if one is empty
if (a.isEmpty() && b.isEmpty()) return true; // check if both are empty
element_a = a.pop(); // grab elements and compare them
element_b = b.pop();
if (((element_a==null) && (element_b!=null)) || !element_a.equals(element_b)) {
a.push(element_a); // if they are not equal, restore them and return false
b.push(element_b);
return false;
}
result = compareStacks(a, b); // compare shortened stacks recursively
a.push(element_a); // restore elements
b.push(element_b);
return result; // return result from recursive call
}
With recursion it always helps to think of it as 2 parts, a "Setup" and a recursive function. Your setup would create the proper situation (create the two stacks, pass them in, etc) and then calls the recursive method and when the recursive method is done, report the results.
In your case you probably want this signature for the "recursive" method:
public boolean compareStacks(Stack one, Stack two)
If that method pops & compares the top tow elements of the stack, it can return false right then (saying they don't compare). If they do, you now have two stacks, each one shorter than before. You already know how to compare those two stacks, right (You just wrote the method to do so!).
at the end you can "Push" your one element back onto each stack to restore it's previous state before returning.
There will be a little trickiness in restoring the stack in the case where they don't compare, and ensuring that if the compareStack you call fails it properly passes that up to the previous state, even if the "current" compareStack succeeds, but those are implementation details--just thought I'd mention those so you don't overlook them.
There is a cute solution with Try/finally (no catch, return from within the try and push back onto the stack in the finally) that would make the code pretty slick, but it's easy enough without it.
Related
Trying to be simple:
If I have a Graph of cities like:
Berlin(edges: London, Berlin) --next--> London(edges: Paris) --next--> Paris.
And I have a method to disconnect Nodes e.g.
disconnect(London, Paris);
I want to test (JUnit) if the disconnect was successful. My idea: write a method isStillConnected(London) which returns false, if London has no edge-list/ if edge-list is null, else true. Code idea:
public boolean isStillConnected(ListItem<Node<City, Road>> berlin) {
boolean edgeExists = false;
if(berlin.key.edgesGoingToHere.key.whereEdgeGoesTo != null) {
edgeExists = true;
}
return edgeExists;
}
PROBLEM: If the edge hasn't got an edge (which I am requesting), there is a NULLPOINTER because I want to access "whereEdgeGoesTo" which is null.
edgesGoingToHere is the head of the Edge-list.
whereEdgeGoesTo is the Node, where the Edge is pointing at.
Thanks for any answer!
I'm not sure I understand your objects structure just by looking at that small portion of code, but assuming that the if statement is checking the right values, to avoid a nullPointerException, instead of reading the values in the list and comparing them to null check the size of the list using .size() and return true if that value is higher than 0.
I am looking into the implementation of Streams::findLast from Guava and while trying to understand it, there were a couple of things that simply I could not grasp. Here is it's implementation:
public static <T> java.util.Optional<T> findLast(Stream<T> stream) {
class OptionalState {
boolean set = false;
T value = null;
void set(#Nullable T value) {
set = true;
this.value = value;
}
T get() {
checkState(set);
return value;
}
}
OptionalState state = new OptionalState();
Deque<Spliterator<T>> splits = new ArrayDeque<>();
splits.addLast(stream.spliterator());
while (!splits.isEmpty()) {
Spliterator<T> spliterator = splits.removeLast();
if (spliterator.getExactSizeIfKnown() == 0) {
continue; // drop this split
}
// Many spliterators will have trySplits that are SUBSIZED even if they are not themselves
// SUBSIZED.
if (spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
// we can drill down to exactly the smallest nonempty spliterator
while (true) {
Spliterator<T> prefix = spliterator.trySplit();
if (prefix == null || prefix.getExactSizeIfKnown() == 0) {
break;
} else if (spliterator.getExactSizeIfKnown() == 0) {
spliterator = prefix;
break;
}
}
// spliterator is known to be nonempty now
spliterator.forEachRemaining(state::set);
return java.util.Optional.of(state.get());
}
Spliterator<T> prefix = spliterator.trySplit();
if (prefix == null || prefix.getExactSizeIfKnown() == 0) {
// we can't split this any further
spliterator.forEachRemaining(state::set);
if (state.set) {
return java.util.Optional.of(state.get());
}
// fall back to the last split
continue;
}
splits.addLast(prefix);
splits.addLast(spliterator);
}
return java.util.Optional.empty();
}
In essence the implementation is not that complicated to be honest, but here are the things that I find a bit weird (and I'll take the blame here if this question gets closed as "opinion-based", I understand it might happen).
First of all is the creation of OptionalState class, this could have been replaced with an array of a single element:
T[] state = (T[]) new Object[1];
and used as simple as:
spliterator.forEachRemaining(x -> state[0] = x);
Then the entire method could be split into 3 pieces:
when a certain Spliterator is known to be empty:
if (spliterator.getExactSizeIfKnown() == 0)
In this case it's easy - just drop it.
then if the Spliterator is known to be SUBSIZED. This is the "happy-path" scenario; as in this case we can split this until we get to the last element. Basically the implementation says: split until the prefix is either null or it's empty (in which case consume the "right" spliterator) or if after a split the "right" spliterator is known to be empty, consume the prefix one. This is done via:
// spliterator is known to be nonempty now
spliterator.forEachRemaining(state::set);
return java.util.Optional.of(state.get());
Second question I have is actually about this comment:
// Many spliterators will have trySplits that are SUBSIZED
// even if they are not themselves SUBSIZED.
This is very interesting, but I could not find such an example, would appreciate if someone would introduce me to one. As a matter of fact, because this comment exists, the code in the next (3-rd part of the method can not be done with a while(true) like the second), because it assumes that after a trySplit we could obtain a Spliterator that is SUBSIZED, even if our initial one was not, so it has to go to the very beginning of findLast.
this part of the method is when a Spliterator is known not to be SUBSIZED and in this case it does not have a known size; thus it relies on how the Spliterator from the source is implemented and in this case actually a findLast makes little sense... for example a Spliterator from a HashSet will return whatever the last entry is in the last bucket...
When you iterate a Spliterator of an unknown size, you have to track whether an element has been encountered. This can be done by calling tryAdvance and using the return value or by using forEachRemaining with a Consumer which records whether an element has been encountered. When you go the latter route, a dedicated class is simpler than an array. And once you have a dedicated class, why not use it for the SIZED spliterator as well.
What’s strange to me, is that this local class, which only exists to be used as a Consumer, doesn’t implement Consumer but requires the binding via state::set.
Consider
Stream.concat(
Stream.of("foo").filter(s -> !s.isEmpty()),
Stream.of("bar", "baz"))
The Spliterator representing the entire stream can’t have the SIZED characteristic. But when splitting off the first substream with the unknown size, the remaining stream has a known size.
Test code:
Spliterator<String> sp = Stream.concat(
Stream.of("foo").filter(s -> !s.isEmpty()),
Stream.of("bar", "baz"))
.spliterator();
do {
System.out.println(
"SIZED: "+sp.hasCharacteristics(Spliterator.SIZED)
+ ", SUBSIZED: "+sp.hasCharacteristics(Spliterator.SUBSIZED)
+ ", exact size if known: "+sp.getExactSizeIfKnown());
} while(sp.trySplit() != null);
Result:
SIZED: false, SUBSIZED: false, exact size if known: -1
SIZED: true, SUBSIZED: true, exact size if known: 2
SIZED: true, SUBSIZED: true, exact size if known: 1
But to me, it looks weird when someone tells in a comment to know that splitting can change the characteristics and then doing a pre-test with SUBSIZED, instead of just doing the split and check whether the result has a known size. After all, the code is doing the split anyway, in the alternative branch, when the characteristic is not present. In my old answer, I did the pretest to avoid allocating data structures, but here, the ArrayDeque is always created and used. But I think, even my old answer could be simplified.
I’m not sure what you are aiming at. When a Spliterator has the ORDERED characteristic, the order of traversal and splitting is well-defined. Since HashSet is not ordered, the term “last” is meaningless. If you are radical, you could optimize the operation to just return the first element for unordered streams; that’s valid and much faster.
What is strange, is this condition:
if (prefix == null || prefix.getExactSizeIfKnown() == 0) {
// we can't split this any further
(and a similar loop termination in the SUBSIZED path)
Just because one prefix happened to have a known zero size, it does not imply that the suffix can’t split further. Nothing in the specification says that.
As a consequence of this condition, Stream.concat(Stream.of("foo"), Stream.of("bar","baz")) can be handled optimally, whereas for Stream.concat(Stream.of(), Stream.of("bar", "baz")), it will fall back to a traversal, because the first prefix has a known size of zero.
I am just starting out with java and recursive methods and i need some help:
I need to determine if two Binary Search Trees has exactly the same set of elements, regardless of the structure of the tree.
I have written a method that checks if the the tree contains an element and its called contains()
this is what i got so far:
public boolean sameContents(Node n2) {
if (contains(n2, n2.key) && n2.left == null && n2.right == null) { return true; }
if (contains(n2, n2.key) && n2.left != null) { sameContents(n2.left); }
if (contains(n2, n2.key) && n2.right != null) { sameContents(n2.right); }
return false;
}
Basicly my idea is that the method is running as long as a node still has a child, and if the trees match.
I call the method with for example testTree1.sameContents(testTree2); but the method always returns false...
Can someone point out how this should be done?
The best way to do this is with an Iterator object - if two binary search trees contain the same elements then their iterators' next methods should return the same values (even if their structures are different).
// returns true if the trees are equivalent, else false
Iterator itr1 = tree1.getIterator();
Iterator itr2 = tree2.getIterator();
while(itr1.hasNext() && itr2.hasNext()) {
if(!itr1.next().equals(itr2.next())) {
return false;
}
}
return !itr1.hasNext() && !itr2.hasNext(); // returns true if trees were the same size, else false
You ought to already have an inorder binary tree traversal method, so you've already got an Iterator - just add an ArrayList/Stack to take the place of the call stack so that you can pause the traversal (whenever you would be making a recursive method call, store the current node to your Stack)
There is another way to do that. You can convert your trees into string representations, using pre-order traversal or in-order traversal. It will take O(n) time. Than you can check whether these strings equal or not. It can be done in O(n) time too. So, the total running time is O(n).
This method looks similar to the solution with iterators but this one is more generic, since can be used for 'is-subtree' task (chechs wether tree t1 is subtree of t2). In this case use can use isSubstring() method instead of equals(). If tree t1 is subtree of t2 than t1's string representaion is substring of t2's. The isSubstring() can be done in O(log n) time.
Can you do a inorder traversal on both trees and check if the result of both the traversals are same. If same, could we assume that both trees have the same set of elements.
Recursion is a new practice for me and I am trying to get better at it and understand how the methods return. I have the following program but am unfailiar with how to use the this keyword. Can you please review the code and walk me through the program showing the values held by the variables as the methods execute?
I have tried numerous things to determine how the value answer in the compute method holds 14 after execution can anyone walk me through the first few recursive calls so I can try and figure out the rest?
public class Recurs1 {
public static void main (String [] arg) {
Recurs1 r = new Recurs1();
r.compute();
}
public void compute() {
int [] stuff = {1, 2, 3, 4};
int answer = this.go(stuff, 0);
System.out.println("The answer is " + answer);
}
private int go(int[] numbers, int spot) {
if (numbers.length == spot) return spot;
int value = this.go(numbers, spot + 1 );
return value + numbers[spot];
}
}
Ok so a few things I notice here:
The purpose of go() seems to be calculating the sum of the numbers in the array. If this is the case, your method should look like this:
private int go(int[] numbers, int spot) {
if (numbers.length - 1 == spot) return numbers[spot];
int value = this.go(numbers, spot + 1 );
return value + numbers[spot];
}
This is because numbers.length in this case will return 4, but the last element in this array is at index 3 (arrays are 0-indexed).
This way, when the function is called with the second parameter set to 3, it will return the value of the last element in the array and then the code will "bubble up" (as I like to call it) and calculate the sum of the elements by subsequently returning the current summed value + the value of the current call.
As for your problem with the this keyword, it's actually very simple. this always refers to the current class instance your code is in. In this case, you create a Recurs1 instance called r in your main function so whenever you call a method on that particular object, the this keyword used in those methods will refer to r. If you created multiple Recurs1 objects (each with potential different internal states) in your program, their respective this references would always point to themselves allowing you to access their member variables and methods.
Hope that helps and good luck, recursion is usually what most people have trouble getting their heads around at first but once you get used to it it's pretty cool!
OK so this is not an answer to your question per se, more like a lesson in recursion.
Keep in mind I have never tried to to do this with a java class.
Recursion means a function that calls itself repeatedly until a answer has been reached, or your function detects you are running out of stack space.
You first step into the function determines if you will call yourself.
When you call yourself you will push a new copy of the data onto the stack and begin executing. I think in the case of java you will allocate a new object into the heap ( don't quote me on this ) and each invocation will have a new set of variables that get populated with new values.
As you recurse deeper and deeper you simply allocate new copies of the object until you find the answer or run out of memory.
If you find the answer you then return the result to the previous level in the stack of objects eg:
int foo(int i ){
if(some condition){
return foo(i);
} else
return i
}
as You can see if the condition tests true the foo() keeps getting called. Now at each call, the variables of foo() are saved for as many levels deep as you go. If the condition tests false then each instance of foo() returns to the previous until you are at the original invocation of foo() which then returns to the caller of foo().
Clear as Mud?
We're refactoring a long method; it contains a long for loop with many continue statements. I'd like to just use the Extract Method refactoring, but Eclipse's automated one doesn't know how to handle the conditional branching. I don't, either.
Our current strategy is to introduce a keepGoing flag (an instance variable since we're going to want to extract method), set it to false at the top of the loop, and replace every continue with setting the flag to true, then wrapping all the following stuff (at different nesting levels) inside an if (keepGoing) clause. Then perform the various extractions, then replace the keepGoing assignments with early returns from the extracted methods, then get rid of the flag.
Is there a better way?
Update: In response to comments - I can't share the code, but here's an anonymized excerpt:
private static void foo(C1 a, C2 b, C3 c, List<C2> list, boolean flag1) throws Exception {
for (int i = 0; i < 1; i++) {
C4 d = null;
Integer e = null;
boolean flag2 = false;
boolean flag3 = findFlag3(a, c);
blahblahblah();
if (e == null) {
if (flag1) {
if (test1(c)) {
if (test2(a, c)) {
Integer f = getF1(b, c);
if (f != null)
e = getE1(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
} else {
Integer f = getF2(b, c);
if (f != null)
e = getE2(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
flag2 = true;
}
} else {
if (test3(a, c)) {
Integer f = getF2(b, c);
if (f != null)
e = getE2(a, f);
if (e == null) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
flag2 = true;
} else {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
flag2 = true;
}
}
}
if (!flag1) {
if (d == null) {
list.add(b);
continue;
}
e = findE(d);
}
}
if (e == null) {
list.add(b);
continue;
}
List<C2> list2 = blahblahblah(b, list, flag1);
if (list2.size() != 0 && flag1) {
blahblahblah();
if (!otherTest()) {
if (yetAnotherTest()) {
list.add(b);
continue;
}
blahblahblah();
}
}
}
}
This is one of those fun ones where no single pattern will get you there.
I would work at it iteratively.
First I'd try to see if I couldn't use an early continue to remove one of those levels of ifs. It's much clearer code to check for a condition and return early (or in your case continue) than to have deeply nested ifs.
Next I think I'd take some of the inner chunks and see if they couldn't be extracted into a separate method. It looks like the first two big blocks (within the "if (test2(a, c)) {" and its else statement) are very similar. There is cut and paste logic that should be the same.
Finally after that stuff is cleared up, you can start looking at your actual problem--you need more classes. This entire statement is probably a three line polymorphic method in 3-5 sibling classes.
It's very close to throw-away and rewrite code, once you identify your actual classes, this entire method will vanish and be replaced with something so simple it hurts. Just the fact that it's a static utility method should be telling you something--you don't want one of those in this type of code.
Edit (After looking a little more):
There is so much here it would be really fun to go through. Remember that when you are done you want no code duplication--and I'm pretty sure this entire thing could be written without a single if--I think all your ifs are cases that could/should easily be handled by polymorphism.
Oh, and as an answer to your question of eclipse not wanting to do it--don't even TRY automatic refactoring with this one, just do it by hand. The stuff inside that first if() needs to be pulled out into a method because it's virtually identical to the clause in its else()!
When I do something like this, I usually create a new method, move the code from the if into the new method (leaving just a call to the new method inside the if), then run a test and make sure you didn't break anything.
then go line by line and check to ensure there is no difference between the if and its else code. If there is, compensate for it by passing the difference as a new variable to the method. After you're sure everything is identical, replace the else clause with a call. Test again. Chances are at this point a few additional optimizations will become obvious, you'll most likely lose the entire if by combining it's logic with the variable you passed to differentiate the two calls.
Just keep doing stuff like that and iterating. The trick with refactoring is to use Very Small Steps and test between each step to ensure nothing changed.
continue is basically an analogue of an early return, right?
for (...) {
doSomething(...);
}
private void doSomething(...) {
...
if (...)
return; // was "continue;"
...
if (!doSomethingElse(...))
return;
...
}
private boolean doSomethingElse(...) {
...
if (...)
return false; // was a continue from a nested operation
...
return true;
}
Now I must admit that I didn't quite follow your current strategy, so I might have just repeated what you said. If so, then my answer is that I can't think of a better way.
If I were faced with your situation I would look at using other refactoring techniques such as "replace conditional with polymorphism". That said you should always do one thing at a time, so if you first want to extract method you have two options:
Add the "keepGoing" flag
Throw an exception from the method
Of these two options, I think the keepGoing flag is better. I wouldn't stop refactoring after you extract the method. I am sure once you have a smaller method you will find a way to remove this flag and have cleaner logic.
I'm going to summarize the answers here, while accepting Bill K's answer as the most complete. But everyone had something good to offer, and I might use any of these approaches next time I'm faced with this sort of situation.
mmyers: Cut out the loop body, paste it into a new method and replace all the continues with returns. This worked very nicely, although it would have trouble if there were other control flow statements, like break and return, inside the loop.
Bill K: Tease it apart iteratively; look for duplication and eliminate it. Take advantage of polymorphic classes to replace the conditional behavior. Use Very Small Steps. Yes; this is all good advice, with broader applicability than just this specific case.
Aaron: Either use the keepGoing flag to replace the continue or throw an Exception. I didn't try this, but I think the Exception option is a very nice alternative, and one I hadn't considered.