There is an array index out of bounds exception in my recursive function. Can someone try to point out to me why that is the case?
This line: return minChange(a, IntegerList); is having the array index out of bounds exception as well as most likely this line:
return minimumValue(1 + minChange(a - d, integerList), minChange(a, updatedList));
/* Function minChange: Minimum Change
Pseudo-code:
minChange(0, ds) = 0
minChange(a, []) = Failure
minChange(a, d :: ds) = minChange(a,ds) if d > a
minChange(a, d :: ds) = min(1 ++ minChange(a - d, d :: ds) otherwise
*/
public int minChange(int a, List<Integer> integerList) {
//int minimumResult = 0;
int indexNumber = 0;
int d = integerList.get(indexNumber); (line 246)
if(a == 0) {
// If a is 0 return 0
return 0;
} else if(integerList.isEmpty()) {
return -1;
} else if(d > a) {
integerList.remove(indexNumber); // Remove first element from list
// Recursive call to minChange
return minChange(a, integerList); (line 261)
} else {
// Create updatedList and remove first element
List<Integer> updatedList = integerList;
updatedList.remove(indexNumber);
indexNumber++;
return minimumValue(1 + minChange(a - d, integerList), minChange(a, updatedList)); (line 269)
}
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out-of-bounds for length 0
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:246)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:261)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
at AlgorithmsSetZero.minChange(AlgorithmsSetZero.java:269)
How can I fix this array index out of bounds exception. It seems one line needs to be fixed. If so how can I fix this error? What are some ways?
Why it Fails:
A specific sequence of events that leads to the out of bounds exception would be, for example:
minChange(1, [4]) // goes into second-to-last (else if) case, since 4 > 1. 4 is then removed.
minChange(1, []) // crashes
It's not clear what your code was intended to do in this case, since your pseudo-code doesn't define minChange(a, ds).
Even if we stipulate that the input list has to have more than one item, we'll often hit this same case:
minChange(5,[4, 8])
minChange(1,[8])
minChange(1,[])
I'm not sure what you intended to happen here, but, anyway, there are other issues...
Bugs:
There is very likely a bug in your code with this line:
// this just creates another reference to the existing list
// https://stackoverflow.com/questions/6536094/java-arraylist-copy
// meaning: both recursive calls will operate on the same list
// even though one uses the "updatedList" reference and one uses "integerList"
List<Integer> updatedList = integerList;
Also, the use of indexNumber indicates a bug, since it's only ever used when it has value 0 - the incrementing is pointless. Remember that local variables in the function are getting 'reset' in each recursive call, unless you pass them as a parameter.
Debugging Strategies:
First, clarify what you actually want the algorithm to do.
Then, check what it's actually doing. As a debugging technique, I would recommend adding some print statement at the start of the function call:
System.out.println("minChange(" + a + ", " + integerList + ")");
...so that you can see a log of what happened before the crash. You can also use a debugger for this purpose.
Finally, once it works on some simple cases, write a fuzz tester that checks your algorithm on a bunch of random lists and as of different sizes, to see if there are any cases that you missed.
Related
My program looks like this:
The input array is [1,2,3,4], the target is 7 and the output should be [2,3]
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
// nums.length-1 why is cannot be minus 1
for (int i = 0; i < nums.length-1; i++){
int result = target - nums[i];
if (map.containsKey(result)){
return new int[]{i,map.get(result)};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("No result.");
}
There will be error.
Exception in thread "main" java.lang.IllegalArgumentException: There is no two numbers in the list can add to the target.
at Solution.twoSum(Solution.java:12)
at __DriverSolution__.__helper__(__Driver__.java:8)
at __Driver__.main(__Driver__.java:54)
But change the search length by plus 1, there will succeed.
The correct code is like this
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> map = new HashMap<>();
// the correct answer is no minus 1 in i < nums.length
for (int i = 0; i < nums.length; i++){
int result = target - nums[i];
if (map.containsKey(result)){
return new int[]{i,map.get(result)};
}
map.put(nums[i],i);
}
throw new IllegalArgumentException("No result.");
}
Can anyone help me why this happens, why could not use minus 1 here
i < nums.length
The number 12 line is
throw new IllegalArgumentException("No result.");
This is straight forward:
if (map.containsKey(result)){
return new int[]{i,map.get(result)};
will abort/break/end the enclosing method.
In other words: when a certain condition is met, the method stops within the loop.
If that condition is never met, then the loop is repeated, and then, that hardcoded, unconditional throws kicks in.
Given the edit to the question: the point here is that you wrote some pretty hard to understand code. The naming of your variables doesn't tell us anything about their intended usage.
I can only repeat what was said: this code implements some sort of algorithm. The algorithm is supposed to identify those two indexes in an input array that added together result in some "target sum". The algorithm uses a map that uses
a value from the input array as map key
the index of that value as map value
It seems that when you don't iterate to the very end of the indexes, you miss a correct condition and therefore throw.
But the real answer isn't me telling you what your code does. The real answer is that you either use a debugger to understand what your code does, or to take a piece of paper and a pen to manually run your code.
Again: this is your code, it is doing what you put into code, so you should step back and slowly, step by step dive into it to understand what exactly it is doing.
While working on some java project I encountered this peculiar error:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 2
How can there be an index out of bounds exception? Index 1 means it tries to get the second element, Size 2 means there are 2 elements, so there shouldn't be a problem, no?
Context:
I have the following function:
public int howManyAgents(){
// cell is a class that can have 0 or multiple objects
// I get a list of cells that contain at least 1 agent
List<Cell> cellsWithAgents = getNonEmptyCells();
// initializing a counter
int agentsCount = 0;
for(int i=0; i<cellsWithAgents.size(); i++){
// For every cell in the list I add to the counter the number of
// agents that cell contains
agentsCount += cellsWithAgents.get(i).howManyAgents();
}
return agentsCount;
}
Now, the problem was that I got a null pointer exception at the line:
agentsCount += cellsWithAgents.get(i).howManyAgents();
I want to debug the code, but this function is called many times while the program is running and the null pointer exceptions comes up at different points in time (after 10 seconds after 1 minute after 5 minutes). So I tried to come up with a method to have e breakpoint when the cell is null so I came up with this code:
public int howManyAgents(){
// cell is a class that can have 0 or multiple objects
// I get a list of cells that contain at least 1 agent
List<Cell> cellsWithAgents = getNonEmptyCells();
// initializing a counter
int agentsCount = 0;
for(int i=0; i<cellsWithAgents.size(); i++){
int pass;
if (null == cellsWithAgents.get(i))
pass = 1; // breakpoint here
// For every cell in the list I add to the counter the number of
// agents that cell contains
agentsCount += cellsWithAgents.get(i).howManyAgents();
}
return agentsCount;
}
Of course, it is not the best method. The most logical way is jut to surround the code with try/catch and put the breakpoint there. The point is that the code above didn't work. It did not stop at the breakpoint but instead it threw the index out of bounds exceptions at the line:
if (null == cellsWithAgents.get(i))
Why? How can it be possible to throw an index out of bound exception if apparently the index is in bounds?
Edit: changed a mistake in copying the code
Update:
I have tried to see why the null pointer exception appears with a try/catch and put a breakpoint there. It seems that cellsWithAgents sometimes contains a null. This is, most probably because of concurrency as #rlinden stated.
About concurrency: there are some cells that can contain agents. There is a variable number of agents that can move between the cells. There is a special agent that tries to count how many moving agents there are (using this function).
So, only one agent (thread) can use this function, but multiple agents can modify cells (and thus mess with getNonEmptyCells() and howManyAgents() results).
Still, how it is possible to get index out of bounds with size 2 and index 1? It is not possible because of the concurrency, is it? Because only this thread can change the list cellsWithAgents. So, even if one of the elements in the list becomes null, the list still contains that number of pointers, so the size of the list cannot change. Or can it in some way that I miss?
And how can it be explained that the stack trace prints Index:1 Size: 2?
New Idea
Try changing the loop and see if the error persists:
int agentsCount = 0;
for(Cell cell : getNonEmptyCells()) {
if(cell != null) {
agentsCount += cell.howManyAgents();
} else {
System.out.println("Found a null cell");
}
}
I would like to see the code of the method getNonEmptyCells(). If your program is actually multithreaded and this function returns a fixed List that is changed at every interaction, then it is possible that changes in following executions have affected the previous, unfinished ones.
This is due to the fact that the line cellsWithAgents = getNonEmptyCells(); does not create a copy, but a reference to the return value of getNonEmptyCells(). So, if this method reuses the return object, it is possible that the first execution would believe there was two, but the concomitant thread changed the content size to less than 2.
The problem is, program is throwing exception at cellsWithType.get(i). What you can do is either put a breakpoint at if (null == cellsWithType.get(i)) and try debug it. Or change it to,
if (i >= cellsWithType.size())
pass = 1; // breakpoint here
I have been working on a few projects lately that use a flood fill on a 2D array to create a grid map for a game.
Part of the flood fill algorithm I am using grabs the neighboring "cells" in the grid and floods them if they are an open space and ignores them if they are not.
However, because I am grabbing neighbor cells, I am grabbing items from the array relative to the current cell like this: grid[y][x-1].
Obviously, when x == 0 an out of bounds error is thrown. In order to address this I have been using a conditional statement to check that the index I am accessing is in the array. Like this:
if(x - 1 >= 0){do what I need to that neighbor}
I know I can also address the error by using a try catch.
However, I am not sure which is the proper solution.
There are a few specific questions I have:
1) Does using the conditional method to prevent an error from occurring, require more overhead and create less efficiency? (I may be flooding thousands of cells)
2) How exactly does the catch block work? Is it conditionally checking for errors in the background some how?
I also made a very small demo code to show you exactly what I am talking about, just scaled down:
public static void main(String[] args) {
//declare our test array and initialize size 3
String [] testArray = new String[3];
//This is here for one of the methods I have been trying to avoid errors on
int indexAdjuster = 5;
//this the index of the array we are adjusting
int i = 0;
//now throw an error! uncomment to confirm there is an error if you want
//testArray[i-indexAdjuster] = "error";
//testArray[i+indexAdjuster] = "error";
//IGNORE the error with a try catch
try{
//this would result in an out of bounds exception below index 0 (-5 specifically)
testArray[0-indexAdjuster] = "error";
//this would result in an out of bounds exception above index 2 (5 specifically)
testArray[0+indexAdjuster] = "error";
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("There was an error, but I ignored it");
}
//PREVENT an error with a condition test
//it first checks if the adjusted index is at least 0
//then it checks if the adjusted index is less than the length of the array
if(i - indexAdjuster >= 0 && i + indexAdjuster < testArray.length){
//this would result in an out of bounds exception below index 0 (-5 specifically)
testArray[0 - indexAdjuster] = "This would be an error, but it is prevented";
//this would result in an out of bounds exception above index 2 (5 specifically)
testArray[0 + indexAdjuster] = "This would be an error, but it is prevented";
}else{
System.out.println("We just prevented the error");
}
System.out.println("Test Complete");
}
It depends, specifically on what you primary focus is: Speed or clean code.
If the error condition occurs rarely and the check is costly, catching an exception may be cheaper than checking beforehand. This conflicts the commonly accepted rule that catch blocks should not be used for regular flow control. Exceptions should be used to catch unexpected error conditions, an index outside an array is hardly unexpected.
The test can also be extracted into a separate method, making the code easier to read:
static boolean isValidIndex(String[] array, int i) {
return i >= 0 && i < array.length;
}
Or use a resilient access method:
static String getIndex(String[] array, int i) {
return i >= 0 && i < array.length ? array[i] : null;
}
(You may want to replace null with a constant value indicating an invalid value).
In your code you can simply use the getIndex() method for whatever index you calculated and act on the value it returns instead of the index. Same can be done for assigning to an index, if its appropiate to just ignore attempted assignments to non-existing indices:
static void setIndex(String[] array, int i, String value) {
if (i >= 0 && i < array.length)
array[i] = value;
}
The main issue you face is deciding if an out-of-bounds condition is just a normal case that has a reasonable default handling option or if it represents a real error that warrants aborting the method or program.
If its a real error condition, don't prevent it, don't catch it. Let it throw and bubble up the call stack. Whatever caller level initiated the whole action should be the one that responds to the execption. Its important to decide sensibly who is responsible for the handling, a deep-down detail method has often not enough information to make a reasonable decision what an error means - in those cases assign the responsibility to the caller (repeat until the caller can make the decision).
Using if statement to check your boundaries cause lots of overhead in each loop iteration.
I suggest you allocate a bigger array by 1 like:
String [] testArray = new String[3+1];
This cause that you don't need any if condition.
In response to your question about exception handling, it does not run any condition in background. It runs your code and after causing access violation determines you catch clauses.
I have a Stack variable (java collection) which holds five integers and I was also given one int variable. Is it possible to sort the numbers in the given stack. I am not able to solve that. Please post here if you have ideas.
Stack<Integer> s = new Stack<Integer>();
s.push(5);s.push(3);s.push(4);s.push(1);s.push(1);
int a;
We should not create any new variable except the one given in the above code snippet and also should not use Collections.sort(s).
Terribly inefficient, but respects the rules :)
Stack<Integer> s=new Stack<Integer>();
s.push(5);s.push(3);s.push(4);s.push(1);s.push(1);
int a = -1;
while (a == -1) { // Here 'a' is used as a kind of boolean that tells us whether we need to keep checking for items to reorder or not.
for (a = 0; a < s.size() - 1; a++) { // Now 'a' becomes stack element's index.
if (s.get(a) > s.get(a + 1)) {
a = s.remove(a); // Here 'a' again changes meaning and holds the value that needs to be reordered.
s.push(a);
a = -1; // And here, 'a' is back to being used as a kind of boolean flag to control the outer loop.
break;
}
}
}
EDIT:
Basically, I take advantage of the fact that I know that Stack extends Vector. So I don't actually have to use only the standard Pop and Push methods to access/remove elements. I can use normal List methods.
And then, I just squeeze the most use I can from a by using it for different purposes at different times (exit flag, loop index, temp storage for value to reorder). Normally a very bad programming practice.
So the algorithm is basically that I loop through the Stack elements. Any time I find an element that is greater than the next, then I remove it, and then place it at the end of the Stack. At that moment, I stop the loop, and reset a to -1 to make sure I start the loop again. I keep doing this until I am able to loop through all the stack items without needing to reorder anything.
EDIT 2:
Here is another alternative that is a bit more complicated to read, but still respects the rules, and performs better following the bubble sort pattern. The principles used are pretty much the same as my first attempt (abusing the Stack as a List + using variable a for multiple uses).
Stack<Integer> s=new Stack<Integer>();
s.push(5);s.push(3);s.push(4);s.push(1);s.push(1);
int a = -1;
while (a < 0) { // keep looping if the previous loop performed at least one swap.
a = 0;
// if 'a' is >= 0, then it simply holds the index.
// if 'a' < 0, then the index can be obtained by applying the bitwise complement operator.
while ((a < 0 ? ~a : a) < (s.size() - 1)) { // loop all items except the last one.
if (s.get(a < 0 ? ~a : a) > s.get((a < 0 ? ~a : a) + 1)) { // if this item is greater than the next, a swap is needed.
s.insertElementAt(s.remove(a < 0 ? ~a : a), (a < 0 ? ~a : a) + 1); // swap this value with the next.
// If this was not done already, flag the fact that a swap was performed by
// applying the bitwise complement operator to 'a'.
// This serves as a flag to let the outer loop know
// that we'll need to perform the stack loop again.
if (a >= 0) {
a = ~a;
}
}
// increment index. Or if the bitwise complement operator was applied,
// then go the opposite way since the value is now negative.
if (a >= 0) {
a++;
} else {
a--;
}
}
}
EDIT 3: Revised my last algorithm to use the bitwise complement operator rather than Math.abs().
Also, I would like to point out that, unlike some other clever attempts, this algorithm doesn't really have any limitations. It won't potentially suffer from a StackOverflowException because of too many recursive calls, because no recursion is used. Memory used is stable. And you can have any int value in the Stack, even negative ones, and it will work fine.
It's possible to do, but you're going to be cheating a little bit - you're going to use a second stack to do it.
I don't mean that you're explicitly declaring another stack; you're going to be recursing through this method.
Bear in mind that this approach has some limitations; it can handle sequential data just fine (that is, it can reverse a stack just fine), but dealing with more jumbled data is a lot trickier as we can only see up to two elements in the future (peek and holder).
This also inverts the approach and doesn't order them in a way you'd prescribe (1 to 5), but figuring out the correct condition from the code should be a trivial matter.
The approach is:
Handle null and empty stacks by returning what was given to us
Handle a stack of size 1 by returning what was given to us
In the process, we pop the stack and store that in the holder variable.
If what's in the stack next is less than the holder variable, we act:
Pop the stack again, multiply it by 10, and add this to the holder. We do the multiplication here so that we can (roughly) store two ints at once.
Push the remainder value (holder % 10) into the stack.
Recurse, repeating the instructions.
Once recursion has exhausted, we push the value we multiplied by 10 back onto the array by dividing the holder by 10.
Otherwise, we put back what we had found and return the stack.
public Stack<Integer> sortStack(Stack<Integer> stack) {
// no-op on empty stacks
if(null == stack || stack.empty()) {
return stack;
}
// pop stack and place in holder
while(true) {
int holder = stack.pop();
// no-op on stacks of size 1
try {
stack.peek();
} catch(EmptyStackException e) {
// Stack only had one element; put it back and return the stack
stack.push(holder);
return stack;
}
if(stack.peek() < holder) {
holder += stack.pop() * 10;
stack.push(holder % 10);
stack = sortStack(stack);
stack.push(holder / 10);
} else {
//put it back
stack.push(holder);
break;
}
}
return stack;
}
Since Stack implements List and Integer implements Comparable just:
Collections.sort(s);
You can use bubble sort to do it, as the following:
Stack<Integer> s = new Stack();
s.push(5);
s.push(3);
s.push(4);
s.push(1);
s.push(1);
int a = 0;
while (a != s.size() - 1) {
if (a != s.size() - 1) {
if (s.elementAt(a) >= s.elementAt(a + 1)) {
a++;
} else {
s.push(s.remove(a));
a = 0;
}
}
}
System.out.println(s.toString());
Here i found the perfect answer from geeksforgeeks which uses recursion.
http://www.geeksforgeeks.org/sort-a-stack-using-recursion/
Just posting the same algorithm here.
Algorithm:
We can use below algorithm to sort stack elements:
sortStack(stack S)
if stack is not empty:
temp = pop(S);
sortStack(S);
sortedInsert(S, temp);
Below algorithm is to insert element is sorted order:
sortedInsert(Stack S, element)
if stack is empty OR element > top element
push(S, elem)
else
temp = pop(S)
sortedInsert(S, element)
push(S, temp)
I need to write a method that checks how many possible ways there are to finish a grid (a 2D array).
the movement inside the grid is like this:
start with [0][0] take the number inside there (for instance 14) then go to either
[array.[0][0]%10][array.[0][0]/10] or [array.[0][0]/10][array.[0][0]%10]
for our example:
[1][4] or [4][1]
until you get to the end of the array (bottom right corner).
I can get to the end of the array (all possible ways) - my problem is to count how many times I actually finished the array - I can not use a variable outside of the method, and the method has to be recursive.
this is the code :
private static int howMany(int[][] array, int y, int x, int count) {
if(y+(array[y][x]%10) < array.length && x+(array[y][x]/10)< array[y].length && array[y][x]!=0) {
System.out.println("["+y+"]["+x+"] is: "+array[y][x]);
howMany(array, y+(array[y][x]%10), x+(array[y][x]/10),count);
}
if(y+(array[y][x]/10) < array.length && x+(array[y][x]%10)< array[y].length && array[y][x]!=0) {
System.out.println("["+y+"]["+x+"] is: "+array[y][x]);
howMany(array, y+(array[y][x]/10), x+(array[y][x]%10),count);
}
if(y==array.length-1 && x==array[y].length-1) count++;
return count;
}
this is obviously wrong and will return what count was in the first place, I tried many other ways but to no avail...
here's the full class (with an array to test):
link to full class
edit: a big Thanks to everyone for their help!
The count is already returned from each call to howMany. I think you just need to save it:
count = howMany(array, y + (array[y][x] % 10), x + (array[y][x] / 10), count);
Do this inside both if blocks. I made this change in your linked code and got the expected result (3).
You are already on the right track, since your method signature returns an int. You should define a variable to hold the count, increment it for the primary recursive call, and add to it the result of the recursive method itself. Passing the count into the each recursive call is unnecessary and should be removed.
Return 1 if you've reached the end of the array (bottom right corner) and 1+howMany(array, newY, newX) otherwise. You don't need to keep the count and pass it every time. The function will work so:
1 + returned value of 2nd call =
1 + 1 + returned value of 3rd call =
1 + 1 + 1 + returned value of 4th call =... and so on.
Finally as result you'll get number of calls which is what you want.