Future code affecting state at an earlier point in time? - java

(EDIT: Please note that TwoStacksAsQueue's and ArrayList's add() methods are different, so there are no recursive calls happening. I am still stuck after using the debugger, which is why I am asking for help here.)
I am in the middle of designing a class of two stacks that functions as a queue. When I run it, the last number it prints is 6 as expected. When I uncomment the last three lines of code, however, it prints 3 instead.
The way I see it, it should make no difference if the while loop at the end of the transfer() method is commented out or not. It comes after the print statement, so how could it possibly affect the output? What am I missing here? I have reduced my code to the minimal reproducible example.
public class TwoStacksAsQueue<T> {
final int stackCapacity;
final Stack<T> stack1;
final Stack<T> stack2;
public TwoStacksAsQueue(int stackCapacity) {
this.stackCapacity = stackCapacity;
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public void add(T something) {
if (stack1.size() + stack2.size() >= stackCapacity * 2)
throw new RuntimeException("Not enough room in either stack; cannot add");
else if (stack1.isEmpty()) {
stack1.push(something);
} else {
int size = stack1.size();
List<T> popped = new ArrayList<>();
while (!stack1.isEmpty()) popped.add(stack1.pop());
stack1.push(something);
for (int i = size - 1; i >= 0; i--) stack1.push(popped.get(i));
if (stack1.size() > stackCapacity) transfer(stack1, stack2);
}
}
private void transfer(Stack<T> from, Stack<T> to) {
List<T> popped = new ArrayList<>();
System.out.println(from.size());
// while (from.size() > stackCapacity) {
// popped.add(from.pop());
// }
}
}
main method:
TwoStacksAsQueue<Integer> twoStacksAsQueue = new TwoStacksAsQueue<>(3);
twoStacksAsQueue.add(0);
twoStacksAsQueue.add(1);
twoStacksAsQueue.add(2);
twoStacksAsQueue.add(3);
twoStacksAsQueue.add(4);
twoStacksAsQueue.add(5);

The commented out lines of code change the behavior when the stackCapacity is exceeded. In your example, that happens when you push the fourth item. You should focus your debugging efforts there instead of waiting until the sixth item is pushed. If you think that code shouldn't be triggered until you hit twice the stackCapacity, you need to rethink that part.
Your code is hard to follow. In particular, I can't tell why you are creating temporary popped lists instead of using stack2. It seems like you think you are transferring values onto stack2, but you are actually putting them in a temporary popped list that then goes out of scope. You'll have an easier time debugging by printing out all the elements of stack1 and stack2 than trying to discern something based on the size.

Related

How to make a sublist refers to his original ArrayList?

I have a homework to do in java about ArrayList and Generics types.
I have 2 classes :
-> CoupeDeA
-> TableauPartiel
CoupeDeA is just a describer from where to where an array is cut.
(It contains only two private integer variables "begin" and "end")
TableauPartiel is the class where the ArrayList is.
My problem is I need to create a method in TableauPartiel like this :
public TableauPartiel<E> coupe(CoupeDeA coupe)
And the TableauPartiel returned needs to be a reference of my intial TableauPartiel. Example :
Integer[] arr = {8,7,6,5};
TableauPartiel<E> tab = new TableauPartiel<>(arr);
TableauPartiel<E> tab2 = tab.coupe(1,3);
tab2.set(1,45);
This code is supposed to set 45 at index 1 of my tab2 and at the same time set 45 at index 2.
But I tried many different ways and I managed to get the sublist, but it is not pointing to my original ArrayList.
For example, I tried something like this :
private ArrayList<E> tableau;
...
public TableauPartiel<E> coupe(Coupe coupe)
throws IndexOutOfBoundsException {
if (coupe.getBegin() >= 0 && coupe.getEnd() <= tableau.size()) {
TableauPartiel<E> tab = new TableauPartiel<>((E[]) new Object[coupe.getEnd()-coupe.getBegin()]);
for (int i = 0; i < coupe.getEnd()-coupe.getBegin(); ++i) {
tab.set(i, this.get(coupe.getBegin()+i));
}
return tab;
} else {
throw new IndexOutOfBoundsException();
}
}
How can I do to get a sublist which refers to his original ArrayList?
I've found a solution for my code with the subList method and by switching the signature of my ArrayList to List but my teacher doesn't want us to use subList finally.
Here is my code with the subList method :
TableauPartiel<E> tab;
if (coupe.getDebut() >= 0 && coupe.getFin() <= taille()) {
if (coupe.getFin() == -1)
tab = new TableauPartiel<>(tableau.subList(coupe.getDebut(),taille()));
else
tab = new TableauPartiel<>(tableau.subList(coupe.getDebut(),coupe.getFin()));
return tab;
} else {
throw new IndexOutOfBoundsException();
}
}
Few small things first:
stick to English words in your code. Especially in names of classes, functions, variables, etc - names have to reveal intentions (without Google Translate). Best not to obtain a bad habit by letting yourself do otherwise.
I am not so sure how your Coupe is expected to work (is 0 a legal min number or 1?) but coupe.getEnd() <= tableau.size() might get out of hand
Now my suggestion for the solution:
I suggest you modify your TableauPartiel class to have start and end integer fields in addition to private ArrayList<E> tableau; reference you already have. Maybe add a new 'copy constructor' accepting an instance of
TableauPartiel (from which you can copy reference to tableau) and two int values indicating which part of the original tableau you can use (trick here is to also look at start and end values of the object you're 'sublisting' from). That way, when you're calling #coupe you can check for validity of the input numbers (as you already do) and simply return a new TableauPartiel object with a reference to this and method params - start and end values. Add some indexes manipulation logic using those start and end to whatever methods your TableauPartiel has and you should be good to go.

Recursive Knapsack returning wrong answer

The following code should be returning 16 as far as I can tell but for some reason, it returns 10. Does anyone know what my bug might be? Basically it's the Knapsack problem in Java and I've ran through the whole code on paper and it seems to return the right answer to me but I cannot figure out why when it's properly run, it returns back 10.
Any help would be much appreciated. Thanks!
import java.util.Stack;
public class knapsackProblem
{
public static int optimalValue(Stack<item> items, int totalWeight)
{
if (items.isEmpty())
return 0;
int value = items.peek().value;
int weight = items.peek().weight;
items.pop();
if (totalWeight<weight)
return optimalValue(items, totalWeight);
return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));
}
public static void main(String args[])
{
int knapsackWeight = 15;
Stack<item> items = new Stack<item>();
items.push(new item(7,10));
items.push(new item(3,6));
System.out.println(optimalValue(items, knapsackWeight));
}
}
class item
{
public int weight;
public int value;
public item(int aWeight, int aValue)
{
weight = aWeight;
value = aValue;
}
}
Your Stack is being modified across the calls. So a line like
return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));
will have two different copies of items for each call. Not what you want.
Instead of using Stack, try changing things around to use an ArrayList. Then pass your index of which item you're evaluating into the optimalValue method instead. This should help you work through the items correctly.
I haven't gone through the whole algorithm, but an obvious problem is that every time you call optimalValue on a Stack, it will pop one or more items from the stack. But a Stack, and the items in the stack, are objects, which means they're passed around by reference. So in this line:
return Math.max(optimalValue(items,totalWeight), value + optimalValue(items, totalWeight-weight));
This calls optimalValue twice. The first time you call it with items as a parameter, optimalValue will pop one or more elements from items. Then the statement calls optimalValue again with items as a parameter--and this will NOT use the same items stack that you passed to the first optimalValue call, but it will use the items with the already-popped-off items still popped off (from the first call). I really doubt this is what you want. If you do things this way, then at some point I think you'll have to make a copy of your Stack. Or you'll need to rethink things and do it a different way (maybe you can use an array or ArrayList, so that the items aren't actually popped off but you could pass a "starting index" from one optimalValue call to the recursive call).
I don't know whether there are other problems with your solution in addition to this one.

What method do I need to use to convert a Producer into a Generator

Assume I have a loop that produces items:
for (int i = 0; true; i++) {
ComplexObject co = new ComplexObject(i);
System.out.println(co);
}
The standard behaviour would be to print a description about the objects, but that does not make that much sense for a real application.
I wish to write a custom iterator (generator) now via which I can obtain the elements.
So I need to write the next() method in such a way that it will return one ComplexObject on every next() call, so it is like one step in a loop.
How would I go about doing that? What general mechanism would you advise me to use?
Keep in mind that I dumbed down the real issue to make it explainable, in reality it is of course not as easy as I have stated here and that is why I need to achieve the exact same mechanism that I have asked.
Regards.
ps. (small rant) What is this bleep about only being allowed to post 6 questions per 24-hour period?
For the example you've given above, you'd need to save some state each time an element was retrieved in order to know what sort of state the next element should have.
Here's an example which does precisely that. I have not tested this, but it should clearly demonstrate what I'm suggesting.
public class ComplexObjectIterator implements Iterator<ComplexObject>{
//track start, so you can tell how many elements were retrieved if you want.
private final int start;
private final int end;
private int position;
public ComplexObjectIterator(int start, int end){
if(start>end) throw new Exception("Start must be less "+
"than or equal to end.");
this.start = start;
this.end = end;
this.position = start;
}
public boolean hasNext(){
return position < end;
}
public ComplexObject next(){
if(position >= end)
throw new Exception("No more elements");
ComplexObject obj = new Complexobject(this.position);
position+=1;
return obj;
}
public void remove(){
if(position >= end)
throw new Exception("No more elements");
position+=1;
}
}
If you truly want an endless iterator, this code can easily be changed to provide that kind of behavior.
Note that iterators are typically used to return elements from an underlying data structure. Because here you have no underlying structure, I'd create a new interface called Generator for your purposes to prevent confusing anyone looking at your code.
Far as the limit on questions, its probably there to prevent malicious users from attacking the site with an overload of questions. Not that you're doing that, just offering a possible explanation.

ArrayList.remove(int) vs ArrayList.remove(Object) in different thread

I have an ArrayList of Minion objects, and when a shield collides with a minion, I want to remove that minion from the ArrayList. However, I can only get it to work in 1 way, but not the other way. can anyone plz explain why?
In all 3 cases, I'm using Android's Renderer's onDrawFrame() method... so I have no control over when it gets called. but here's the code for all 3 ways:
Method 1: (does not work)
public void onDrawFrame(GL10 gl) {
List<Integer> indexesToRemove = new ArrayList<Integer>();
int len = minions.size();
for(int i=0; i<len; i++){
if( OverlapTester.overlapCircleRectangle( (Circle)shield1.bounds, (Rectangle)minions.get(i).bounds) ){ //this tests out to work just fine
indexesToRemove.add(i);
}
}
for(int i=indexesToRemove.size()-1; i>=0; i--){
minions.remove(indexesToRemove.get(i)); //<------ why doesn't this work?
}
}
the problem is that that last line minions.remove(indexesToRemove.get(i)); doesn't ACTUALLY remove the minions. it DOES get called, with the proper index. i've stepped through the debugger, ran it straight up, and the arraylist isn't modified at all. why is this? actually, in the debugger, that line "minions.remove(indexesToRemove.get(i));" gets called a bijillion times.
Method 2: (still does not work)
public void onDrawFrame(GL10 gl) {
synchronized(minions){
List<Integer> indexesToRemove = new ArrayList<Integer>();
int len = minions.size();
for(int i=0; i<len; i++){
if( OverlapTester.overlapCircleRectangle( (Circle)shield1.bounds, (Rectangle)minions.get(i).bounds) ){ //this tests out to work just fine
indexesToRemove.add(i);
}
}
for(int i=indexesToRemove.size()-1; i>=0; i--){
minions.remove(indexesToRemove.get(i)); //<------ why doesn't this work?
}
}
}
In here, I thought... "oh maybe since it's not quite synchronized, the drawFrame sometimes gets called too many times and is accessing the arraylist at the wrong time and i need to lock it. but it still doesn't work. again, that line minions.remove(indexesToRemove.get(i)); gets called properly with the right index, but does NOT actually remove the object. i'm watching my shield on the screen slam right into the minion and nothing happens to the minion (it doesn't get removed from the arraylist)
Method #3 (this actually works)
public void onDrawFrame(GL10 gl) {
ArrayList<Minion> colliders = new ArrayList<Minion>(minions);
int len = colliders.size();
for(int i=0; i<len; i++){
GameObject collider = colliders.get(i);
if(OverlapTester.overlapCircleRectangle((Circle)shield1.bounds, (Rectangle)collider.bounds)){
minions.remove(collider); // <---- why does THIS work instead?
}
}
}
this code works perfectly. the shield smacks the minion and the minion drops dead. as you can see here, the ONLY difference is that i'm using the overloaded ArrayList.remove(object) method instead of removing by index. as in the line minions.remove(collider);. why does THIS work ?
can anyone please explain?
on a side note, aside from storing another instance variable copy of the arraylist, is there a better way to manage ArrayList<Minion> colliders = new ArrayList<Minion>(minions); ?
Note: both Shield and Minion are regular Java objects that have a rectangular shape as boundary. all that math checks out just fine. i've tested it in the debugger and the collision detection is accurate. I'm also updating the bounds/positions accurate in the onDrawFrame() method.
Because ArrayList provides two methods that are:
public E remove(int index)
public boolean remove(Object o)
When you invoke minions.remove(indexesToRemove.get(i)), since indexesToRemove is a List<Integer>, the invocation is bound to the second signature in which you remove an element by directly specifying the object, auto-unboxing doesn't turn your Integer into an int so the element is not found and nothing happens.
Try with: minions.remove((int)indexesToRemove.get(i)) so that static binding of the method is correctly applied.
#Jack's answer is correct. For posterity you should be using an Iterator here that you can remove with inside your loop:
// synchronization wrapper here
Iterator<Minion> iterator = minions.iterator();
while (iterator.hasNext()) {
Minion minion = iterator.next();
if( OverlapTester.overlapCircleRectangle(..., minion.bounds)) {
iterator.remove();
}
}
It's treating Integer as an object ref in the 1st two example, cast it to an int

How does recursion work here?

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?

Categories

Resources