I seem to get an error when I test running my program, which says java.lang.ArrayIndexOutOfBoundsException: -1
Please can anyone give me some advice on how to fix this?
class MineFinderModel {
public static int MINE_SQUARE = 10;
public static int EMPTY_SQUARE = 0;
int num_of_cols;
int num_of_rows;
int[][] the_minefield;
public MineFinderModel(int n_cols, int n_rows) {
num_of_rows = n_rows;
num_of_cols = n_cols;
the_minefield = new int[num_of_cols][num_of_rows];
}
public boolean addMine(int thisCol, int thisRow) {
if (thisCol >= num_of_cols || thisRow >= num_of_rows)
return false;
if (the_minefield[thisCol][thisRow] == MINE_SQUARE)
return false;
the_minefield[thisCol][thisRow] = MINE_SQUARE;
return true;
}
public int getValue(int thisCol, int thisRow) {
if (thisCol >= num_of_cols || thisRow >= num_of_rows)
return 0;
return the_minefield[thisCol][thisRow];
}
public void addMinesToCorners() {
the_minefield[0][0] = MINE_SQUARE;
the_minefield[0][num_of_rows -1] = MINE_SQUARE;
the_minefield[num_of_cols - 1][0] = MINE_SQUARE;
the_minefield[num_of_cols - 1][num_of_rows - 1] = MINE_SQUARE;
}
}
I guess that it should be in the "addMinesToCorners()" function since you are not testing the boundaries.
What about trying to put some if around you variables ?
if(num_of_cols == 0)
if(num_of_rows == 0)
At initialization, this equals "0", and then "0 - 1" gives "-1". Hence the error.
Hope this helps !
All your methods have the max value check but none of them are checking for a negative value in thisRow and thisCol so the addMine() and getValue() will throw an java.lang.ArrayIndexOutOfBoundsException if any of the arguments to these 2 methods is negative.
You can add a condition like
`
if (thisCol >= num_of_cols || thisCol < 0
|| thisRow >= num_of_rows || thisRow <0)
return false
Arrays are zero indexed so your checks are incorrect, e.g., if num_of_cols is 10 then the last position will be 9 but your check will pass if you pass in 10 as thisCol because it is checking against the initialiser value instead of the length of the array.
Try changing your test to
if (thisCol < 0 thisCol >= (num_of_cols - 1) || thisRow < 0 || thisRow >= num_of_rows - 1))
Related
I'm more of an intermediate android dev and I want to learn how to write more clean and effective code, and I've come to this problem on my app that requires to check a bunch of statements like if a variable is less than something or more for each individual rating.
private void rateStock(double peRatio) {
//For Dividend Stocks
if(currentDiv != 0 && fiveYearDiv != 0){
double dividendDiff = currentDiv - fiveYearDiv;
if (peRatio <= 20 && peRatio > 0 && dividendDiff >= 0.01 && payoutRatio <= 0.65) {
int stockRatingDividend = 5;
addItems(stockRatingDividend);
} else if (peRatio > 20 && peRatio <= 25 && dividendDiff >= 0.005 && payoutRatio <= 0.75) {
int stockRatingDividend = 4;
addItems(stockRatingDividend);
} else if (peRatio > 25 && peRatio <= 30 && dividendDiff >= 0.001 && payoutRatio <= 0.85) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
} else if (peRatio > 30 && peRatio <= 35 && payoutRatio <= 0.95) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
} else if( peRatio > 35 && peRatio <= 40 && currentDiv > fiveYearDiv && payoutRatio >= 100) {
int stockRatingDividend = 2;
addItems(stockRatingDividend);
} else if( peRatio > 40 || peRatio < 0 && fiveYearDiv > currentDiv && payoutRatio >= 100) {
int stockRatingDividend = 1;
addItems(stockRatingDividend);
} else {
int stockRatingDividend = 0;
addItems(stockRatingDividend);
}
}
}
As you can see by the code above it's very messy and cluttered and doesn't even work correctly, because there are too many conditions it has to check and it usually doesn't fit into any else if statement and just returns 0
I know it might be a lot but can someone at least guide me to a post or something on how I could write more effective and clean code rather than a cluttered mess of else if statements for this block of code?
the possible values of your parameters are not fully represented by the choices in youre if/else branches. So the best way would be to implement a class which decides by itself, if it is responsible for the computation of your single resulting value stockRatingDividend. a sketch of this (with no getters, constructor and no handling, if one border for the min/max is not set) would be:
public class SRDResolver {
public class SRDRolver {
private int peRatioMin;
private int peRatioMax;
private double dividendDiffMin;
private double dividendDiffMax;
private double payoutRatioMin;
private double payoutRatioMax;
private double stockRatingDividend;
public boolean hasSolution(int peRatio,double dividendDiv,double payoutRatio){
return peRatio > peRatioMin && peRatio <= peRatioMax && dividendDiv > dividendDiffMin && dividendDiv <= dividendDiffMax && payoutRatio > payoutRatioMin && payoutRatio <= payoutRatioMax;
}
}
}
then you put the intances in a list. You then get the correct instance from streaming that list with filter(i-> i.hasSolution(...).findFirst(), which gives you an Optional as a result. If it is present, you take it's stockRatingDividend,otherwise you use your fallback value of 0.
That way you can easyily add new instances, if you need,without cluttering if/else. You might add some checks, when you put the instances into the list to ensure, that the number spaces span of the instances do not overlap.
For any future wanderers, that have the same question, I have come up with a solution myself!
What I did was split it into different classes and in the first class ValueLists.java
I created all the ranges and made a getter for the list.
public List<Range> getPeRatioRanges() {
Range range20 = new Range(0, 20);
Range range25 = new Range(21, 25);
Range range30 = new Range(26, 30);
Range range35 = new Range(31, 35);
Range range40 = new Range(36, 40);
List<Range> list = new LinkedList<>(Arrays.asList(range40, range35, range30, range25, range20)); // add in reverse order cuz index = rating
return list;
}
And in the other class CheckRatingOfStock.java I created a simple loop for iterating through the ranges and get the rating.
List<Range> peRatioRanges = getPeRatioRanges();
for (int i = 0; i < peRatioRanges.size(); i++) {
Range range = peRatioRanges.get(i);
int intPERatio = (int) rawPEratio;
if (range.contains(intPERatio)) {
rating = i + 1;
}
}
Here the index of the range is the rating + 1, so if its 0-20 its the rating of 5, because the list is reversed.
This way with 2 blocks of code I avoid a lot of back and forth and the clutter of mass else if statements, and also make it much more easily maintainable and cleaner, atleast in my opinion.
This could be implemented as a method:
static int getIndexOfRange(int intPERatio, List<Range> ranges)
{
for (int i=0; i< ranges.size(); i++)
if (ranges.get(i).contains(intPERatio))
return i+1; //if found, return immediatelly
return -1; //if it reaches this line, means the item was not found
} //return -1 as representation of this
The below two could be combined as it does the same thing.
else if (peRatio > 25 && peRatio <= 30 && dividendDiff >= 0.001 && payoutRatio <= 0.85) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
} else if (peRatio > 30 && peRatio <= 35 && payoutRatio <= 0.95) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
}
Also, I would recommend refactoring the if-else block to a new method which returns stockRatingDividend. This would keep the dividend computation logic separate from the other logic, which would actually make the code more understandable.
if(currentDiv != 0 && fiveYearDiv != 0){
double dividendDiff = currentDiv - fiveYearDiv;
addItems(getStockRatingDividend(/*arguments*/));
}
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 years ago.
I wrote in an exam a backtracking code that moving between cell and counting paths, the conditions are if the next cell is i+k or j+k or i-k or j-k.
the code somehow is still going out of bounds even due I tried to prevent it from doing so.
I tried adding fixing the code by adding +1 in the checking valid move in the "if" conditions.
public class Test3
{
public static int howManyPaths(int [][] mat)
{
return howManyPaths(mat,0,0,0);
}
private static int howManyPaths(int [][] mat, int i, int j, int count)
{
if(i == mat.length-1){return count;}
if(j == mat[i].length-1){return howManyPaths(mat,i+1,0,count);}
count = pathCount(mat,i,j);
return howManyPaths(mat,i,j+1,count);
}
private static int pathCount(int [][] mat, int i, int j)
{
int k = mat[i][j];
if(i < mat.length-1 && mat[i][j] == mat[i+k][j] && i+k < mat.length-1){
return 1 + pathCount(mat,i+k,j);}
if(j < mat[i].length-1 && mat[i][j]==mat[i][j+k] && j+k < mat[i].length-1){
return 1 + pathCount(mat,i,j+k);}
if(i > 0 && mat[i][j]==mat[i-k][j] && i-k > 0){
return 1 + pathCount(mat,i-k,j);}
if(j > 0 && mat[i][j]==mat[i][j-k] && j-k > 0){
return 1 + pathCount(mat,i,j-k);}
return 1;
}
}
the expected is how many paths and the actual results are "out of bounds".
Edited with the fixet code still not working
In your code,
if(i < mat.length-1 && mat[i][j] == mat[i+k][j]){
return 1 + pathCount(mat,i+k,j);}
what will it be, if i+k>=mat.length? Or,
if(j < mat[i].length-1 && mat[i][j]==mat[i][j+k]+1){
return 1 + pathCount(mat,i,j+k);
what will it be, if j+k>=mat[i].length? Or,
if(i > 0 && mat[i][j]==mat[i-k][j]){
return 1 + pathCount(mat,i-k,j);}
what will it be, if i-k<0? Or,
if(j > 0 && mat[i][j]==mat[i][j-k]){
return 1 + pathCount(mat,i,j-k);}
what will it be, if j-k<0?
Handle these cases as well. See, being i>0, still i-k can be less than or equal to 0. This is the trick in your case.
Hope you got it now.
Edit:
After you editing your code still it is getting the same exception as you are accessing the indexes and then checking if the index is a valid one.
Not this:
if(i < mat.length-1 && mat[i][j] == mat[i+k][j] && i+k < mat.length-1)
Instead, you must write:
if(i < mat.length-1 && i+k < mat.length-1 && mat[i][j] == mat[i+k][j])
Same for others as well.
By doing this, you will be able to get rid of java.lang.ArrayIndexOutOfBoundsException
I received an error when compiled the code below, which is "incomparable types: int and " on line 10.
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || k <= 0 || t < 0 || nums.length < 2) return false;
TreeSet<Integer> set = new TreeSet<>();
for (int i = 0; i < nums.length; i++) {
int floor = set.floor(nums[i] + t);//return largest number smaller than nums[i] + t or null
int ceil = set.ceiling(nums[i] - t);//return least number larger than num[i] - t or null
if ((floor != null && floor >= nums[i]) || (ceil != null && ceil <= nums[i])) {
return true;
}
set.add(nums[i]);
if (set.size() > k) {
set.remove(nums[i - k]);
}
}
return false;
}}
but if I add final keyword before treeset, floor and ceil, the code will be compiled successfully. Could anyone help me explain what's going on? Thanks.
...
final TreeSet<Integer> set = new TreeSet<>();
for (int i = 0; i < nums.length; i++) {
final Integer floor = set.floor(nums[i] + t);//return largest number smaller than nums[i] + t or null
final Integer ceil = set.ceiling(nums[i] - t);//return least number larger than num[i] - t or null
...
int floor defines floor as a basic int type. Integer floor defines floor as a non-trivial, class type. null is used only with non-trivial types
It has nothing to do with the final keyword (It will work without it anyway). You just can't compare a primitive value (int) to null. Instead, you should use a corresponding object (Integer).
I have a class that generates a random number within a given interval.
public class Dice{
//code.....
public int throwDice(){
Random randomGen = new Random();
int min = 1;
int max = sides; //sides gets a value earlier in the class
int randomNum = randomGen.nextInt((max - min) + 1) + min;
return randomNum;
}
Then the assignment says that I'm going to use a boolean method that looks like this (with my already written code in it as well):
private boolean step(){
int res = this.dice.throwDice();
int startpos = this.bridge.getFirst();
if (res == 10){ //this works
return false;
}
else if (res => 7 && res <= 9 ){ //but the error occurs here
//code....
return true;
}
What I need to do is check if the generated random number in the throwDice() method is within a certain interval of numbers.
The problem is that I get an error that says that I can't convert an int to a boolean. Is there a way to get around this? Or do I have to rethink my whole solution?
=> should be the other way around.
else if (res => 7 && res <= 9 ){
should be
else if (res >= 7 && res <= 9 ){
Equality and Relational Operators
== Equal to
!= Not equal to
> Greater than
>= Greater than or equal to <-----
< Less than
<= Less than or equal to
Source Equality and Relational Operator
i need help on a verification on a string
I have to write a method that verify if 2 parameters of the method have the same length and if the second one have numbers between 0 and 3.
Let's see what i wrote :
public static boolean coupEstValide( String combinaison, String coup ){
boolean res = true;
if(combinaison.length() == coup.length()){
int i = 0;
while(i < coup.length() && res == true){
char t = coup.charAt(i);
if(t <= 0 && t >= 3)
res = false;
i++;
}
}
return res;
in my opinion, this should work... But if i do this :
coupEstValide("555", "104");
it should tell me false but it it's telling me it's true.
Do you guys see what's wrong ?
Thanks
When you compare Character with an integer actually ASCII value of that character gets compared with that integer. That's why you keep getting true.
So as already suggested in the comments you should compare it either as if(t >= '0' && t <= '3') or use any Utility method of java.lang such as Character.compare(char lhs, char rhs).
Hope this would be helpful.
Enjoy!
A few of problems in your code:
If the lengths are different, you are still returning true!
Strings are composed of characters. Their value is their character code. 0 to 3 are 48 to 51, respectively. Use character constants not integer constants: if (t == '0') will check if t is the character "0".
Your logic for the comparison isn't right anyways. Using your original (incorrect) example with integers, and correcting from <= and >= based on your comments: if (t < 0 && t > 3) will never be true, t cannot simultaneously be less than 0 and greater than 3. I'll leave the correct boolean statement as an exercise to the reader (hint: or).
Alright, i fixed the problem.
So as you said, i should've use
if(t < '0' || t > '3')
And to fix the problem of the time both are not the same size, i added an else.
So the full code is that :
public static boolean coupEstValide( String combinaison, String coup ){
boolean res = true;
if(combinaison.length() == coup.length()){
int i = 0;
while(i < coup.length() && res == true){
char t = coup.charAt(i);
if(t < '0' || t > '3')
res = false;
i++;
}
}
else
res = false;
return res;
}
Thanks for your help guys !
This would never true. A number can not be less and equal to zero and at the same time greater and equal to 3.
if(t <= 0 && t >= 3)
If you want to evaluate whether a character is between 0 and 3 you must use this:
if(t >= '0' && t <= '3')
Now if you want to evaluate if the character is not between 0 and 3 then try this:
if (t <'0' || t> '3')
String coup = "053";
boolean res = true;
int i = 0;
while (i < coup.length() && res == true) {
System.out.println(coup.length());
int t = Integer.parseInt(coup.charAt(i) + "");
System.out.println("T is " + t);
if (t <= 0 || t >= 3) {
res = false;
i++;
}
System.out.println("Value i " + i);
System.out.println("Value of the Res at last" + res);
}
may be this could be helpful try to convert it to the integer
according to your code
String coup = "053";
boolean res = true;
int i = 1;
while (i < coup.length() && res == true) {
System.out.println(coup.length());
//int t = Integer.parseInt(coup.charAt(i) + "");
char t = coup.charAt(i);
System.out.println("T is " + t);
if (t <= 0 || t >= 3) {
res = false;
i++;
}
System.out.println("Value i " + i);
System.out.println("Value of the Res at last" + res);
}