I'm trying to do a homework assignment. I have to use dynamic programming to display whether the next person to move is in a win/loss state. I don't need help with the actual problem, I need help with an index out of bounds exception I'm getting that baffles me. I'm only going to paste part of my code here, because I only need the for loops looked at. I also don't want anyone in my class seeing all my code and copying it. If you need more data please let me know. So here is the code:
if(primeArray[x] == true){
for(int i = 1; i <= x; i++){
if(primeArray[i]== true){
newRowNumber = x - i;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
}
//COMPOSITE CASE FOR X!
else{
for(int k = 1; k <= x; k++){
if((primeArray[k] == false)){
newRowNumber = x - k;
}
if(dynaProgram[newRowNumber][columnNumber] < minimum){
minimum = dynaProgram[newRowNumber][columnNumber];
}
}
For some reason the if(primeArray[i] == true runs correctly, but I'm getting index out of bounds exception on if(primeArray[k] == false. The only difference between these two is the use of the variable k over i in the for loop.(the for loops are identical) I haven't used either variables anywhere else in my code. I have no idea why this occurs for one but not the other. In both cases, x remains the same number.
I am also getting an index out of bounds exception on the second minimum = dynaProgram[newRowNumber][columnNumber], while the first doesn't encounter an error. I know it's probably a stupid error, but I can't figure it out. If I change the 'k' for loop to k < x the index of out bounds exception in the if(primeArray[k] == false line goes away, but then it isn't correct. (The error on the second minimum = dynaProgram[newRowNumber][columnNumber] doesn't go away however.)
All this code is in a nested for loop which iterates through the rows and columns in the table to fill them in. If I remove the above code and just put dynaProgram[rowNumber][columnNumber] = 1 I don't have an issue, so I don't believe that is the problem.
When accessing an array of length 5 (for example)
int[] fred = new int[5];
the first element will be fred[0] and the last will be fred[4]
So when doing something like:
if(primeArray[i]== true){
Make sure that i is less than the array length. Using a value of i equal to the array length will throw an exception.
Related
I'm trying to write a Java program to calculate the square root of an integer x, without using in-built functions like Math.pow() . This is the approach I tried -
class Solution {
public int mySqrt(int x) {
if(x==0 || x==1)
return x;
// if(x>=2147395600)
// return 46340;
int i;
for(i=1 ; i*i<=x ; i++) {}
return i-1;
}
}
Without the commented part, I start getting errors if x is in the range 2147395600 <= x <= 2^31-1 (which is the upper limit of an int's value range in Java). For instance, for the input x=2147395600, the expected output is 46340 but the actual output is 289398. Why is this happening? Thanks to all in advance.
PS - I am aware there are other (better) methods to solve this problem, but I'd really like to know why this code behaves this way.
Since 46340 * 46340 = 2147395600, when i=46340, x=2147395600 and you reach the condition i*i<=x it evaluates to true since 2147395600 = 2147395600. So the loop counter will incremnet by 1 and in the next iteration we will get i=46341 and i * i will cause an overflow - 46341*46341 = -2147479015.
The loop condition will still be true, since -2147479015 <= 2147395600, and the loop will not stop.
You can replace the <= with =, and check for edge cases that may occur now.
The task was to write a method to return the least value of an array.
Would someone quickly look over my code?
public static int findMinimum (int [] array) {
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
for (int zwiebel= 0; zwiebel < array.length; zwiebel ++) {
if (array [zwiebel] < array [kohlrabi]) {
kohlrabi = zwiebel -1;
break;
}
int spinat = array [kohlrabi];
if (zwiebel == array.length-1) {
return spinat;
}
}
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation
problem: This method must return a result of type int
at Abgabe7.ArrayExercises.findMinimum(ArrayExercises.java:38)
It's a homework for my school and I definitely understood the logic behind it but cannot find my fault.
Thanks Max
I don't think you need to have two loops. One loop would work.
Simply loop though the array keeping a variable which is the lowest you've found.
You should declare a global variable before the loop then use only one for loop in your code as follows:
int zwiebel= 0;
for (int kohlrabi = 0; kohlrabi < array.length; kohlrabi++) {
if (kohlrabi == 0){
zwiebel = array[kohlrabi];
}
if (array[kohlrabi] < zwiebel) {
zwiebel = array[kohlrabi];
}
}
The lowest value in your array is now stored in the variable zwiebel.
The real mistake is that you are not taking the possibility of an empty array into account. One thing to learn in programming is to think of all possibilities (maybe you’ve discovered that already). An array in Java (and most other languages) can have length 0, that is, have no elements in it. When array.length is 0, your outer for loop doesn’t execute, so we get down to the bottom of the method without having returned anything and without having anything to return.
Java is dumb, but nevertheless smart enough to discover this problem for you. When your method is declared to return an int, it insists that it too can see that it will return an int in all cases. In your method it cannot, which is what the following message is trying to tell you:
This method must return a result of type int
One possible fix — and I may be showing you something that you haven’t learned in school yet — is to insert the following statement in the end of your method:
throw new IllegalArgumentException("Cannot find the minimum of an empty array");
Throwing an exception is an alternative to returning a value, so this statement will make Java happy. If you actually try to find the minimum of an empty array, your program will crash and give you the message “Cannot find the minimum of an empty array”. But finding the minimum of an array that has numbers in it should work now.
That said the others are correct: Your way of finding the minimum is overly complex. I have been staring at your code and still have not understood how it works. Such code is not good. In real life you will be writing code that others will need to read and change after you, and no one can change code they don’t understand, so your code would not be useful. More important than writing code that works correctly is writing readable code.
Edit: There are variations on how to do this in a simple way. For a school exercise using a for loop I would write:
public static int findMinimum (int [] array) {
if (array.length == 0) {
return 42; // or whichever value is desired in this case
}
int niedrichsteSoWeit = array[0];
for (int index = 1; index < array.length; index++) {
if (array[index] < niedrichsteSoWeit) {
niedrichsteSoWeit = array[index];
}
}
return niedrichsteSoWeit;
}
For production code I probably would not write a method but use the built-in functionality, for example:
IntStream.of(myIntArray)
.min()
.ifPresentOrElse(min -> {
// do something with min
}, () -> {
// do whatever you want to do when the array is empty
});
Don’t worry if you don’t understand a bit of this snippet. It’s mostly for more experienced programmers who might happen to read this answer.
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.
Tried changing around the for loop condition several times, still get ArrayIndexOutOfBounds when I pass zero as a parameter. Every other number works fine, I am trying to account for zero by setting it equal to zero automatically, am I doing that part incorrectly? Everything compiles and runs fine except for zero.
private static int iterativeCalculation(int userEntry)
{
int iterativeArray[] = new int[userEntry + 1];
iterativeArray[0] = 0;
iterativeArray[1] = 1;
for (int i = 2; i <= userEntry; i++)
{
iterativeArray[i] = (3 * iterativeArray[i - 1]) - (2 * iterativeArray[i - 2]);
iterativeEfficiencyCounter++;
}
return iterativeArray[userEntry];
}
public static void main(String[] args) {
System.out.println(iterativeCalculation(0));
}
Tried debugging my way through the code, still not understanding what is going wrong. Would appreciate any help! Thanks!
When you pass zero as parameter, userEntry + 1 = 1.
But here:
iterativeArray[1] = 1;
You are trying to set the second element's value. Remember that length of array is one less than its actual size. So removing this line will fix it. Or use userEntry + 2 instead and alter your loop accordingly.
EDIT:
If you really want to fix first and second element, then use this instead:
int iterativeArray[] = new int[userEntry + 2];
iterativeArray[0] = 0;
iterativeArray[1] = 1;
This will create an array of adequate base size.
And remember, length you enter in [...] while creating array has to be one more than the actual length you want. Because actual array starts counting from 0.
In your case, you were setting length as 1 (minimum). That would create an array which can store only one element; that is iterativeArray[0] = //something. Anything above that is OutOfBounds.
You are setting iterativeArray[1] = 1; regardless of whether or not there are actually 2 or more items in the array. That will be out of bounds with one element.
I think you should step through the code in debugger to best understand what the problem is. You'll see exactly where it's got a problem if you single-step through the code. This is a fundamental technique and tool.
I have an array with 5 size , and I want to assign value from random function if any index doesn't have it.
while(positionXtoStart==array1[0] || positionXtoStart==array1[1] ||
positionXtoStart==array1[2] || positionXtoStart==array1[3] ||
positionXtoStart==array1[4])
{
positionXtoStart = (rand1.nextInt(400) + 1)+30;
}
this solution is ok for small size of array but if i have array with size of 1000, I cant enter 1000 conditions in the while loop.
I tried For-loop with if-else condition in it but the
problem is, I want to check all array indexes at the same time.
Please try to understand what i am asking. I want to check all array index values at the same time (in one shot).
in For-loop, we can check only one value at a time.
If I understand correctly, you just need to loop through the array, checking each value.
for (int i = 0; i < array1.length; i++)
{
if (array1[i] == positionXtoStart)
{
positionXtoStart = (rand1.nextInt(400) + 1)+30;
break; // exit the loop
}
}
are you looking for something like this?
for(int i=0; i<array1.length; i++)
if(array[i] == whatever)
{
// do stuff
}
unfortunately, what you're asking is not possible. Even in your code:
while(positionXtoStart==array1[0] || positionXtoStart==array1[1] ||
positionXtoStart==array1[2] || positionXtoStart==array1[3] ||
positionXtoStart==array1[4])
the computer is checking one condition at a time. It's not doing all the conditions at once, like you may think it is. The code you posted is equivalent to the code #Supericy and #Samiam posted.
Unless there's a reason the forloops doesn't work for your case, I would say go with the answers that are posted here.
If you have to check each entry you have to go trough the whole array. An unordered array in not really suitable for searching trough it. Maybe you should think of changing your data structure into something like a BST so you have a guarantied O(logn) search.
To compare all elements in an unordered array you need linear time.