Why am I getting an array index out of bounds exception? - java

Basically, I have an assignment that requires me to find the mode of a given set of numbers.
This is my Method:
public void findMode (){
/* The vector data is analyzed and transferred into a smaller vector
smallList (0..100). For each occurrence of n in vector data,
smallList[n] is incremented +1. function Largest is then called
to find the largest quantity in vector smallList. The mode(s)
is/are printed out. */
int loop, largest;
int[] smallList = new int[101];
for (int i = 0; i < myHowMany; i++)
{
smallList[myData[i]]++;
}
int max = 0;
for (int i = 0; i < smallList.length; i++)
{
if (max < smallList[i])
{
max = smallList[i];
}
}
//Max is 26
int size = 0;
for (int i = 0; i < smallList.length; i++)
{
if (i == max) size++;
}
int[] modes = new int[size];
int modeIndex = 0;
for (int i = 0; i < smallList.length; i++)
{
if (smallList[i] == max)
{
modes[modeIndex] = smallList[i];
System.out.println(modes[modeIndex]);
modeIndex++;
}
} Everything compiles fine, but when I run this method, I get an out of bounds array method. I have no idea WHY this happens so I
need to know if the community can help me
.
Solved!
Please tell me if I need more information!
edit: I forgot to mention that I get the error here:
modes[modeIndex] = smallList[i];
New Problem:
I fixed the problem from before, but now, I find that my max goes unto the array so that modes = 26(max)

Your error is in this line
if (i == max) size++;
It should be
if (smallList[i] == max) size++;
This is causing the size of modes to be wrong

That should be clear enough: either modeIndex or i exceeds the array size. Since you're looping over smallList with smallList.length, I guess the error is in the modeIndex then. In this case, size (which is used to construct modes) isn't big enough.

if (i == max) size++;
and then
if (smallList[i] == max)
Please check your value for size.

Related

How to get the top 5 numbers from a 2D array of random numbers

I am pretty new to java and am just learning 2D arrays. I am trying to get the top 5 numbers to display from a random list. I think this could work but am not sure why I am getting an error. One other thing is that I cannot use the sort function.
Code here:
public static void main(String[] args) {
//Random Number stuff
Random rand = new Random();
int[] large = new int [5];
int max = 0, index;
int[][] arrSize = new int [4][5];
for (int i = 0; i < arrSize.length; i++) {
for (int j=0; j< arrSize[i].length; j++) {
arrSize[i][j] = rand.nextInt(89) + 10;
System.out.print(arrSize[i][j] + " ");
}
System.out.println();
}
// Top 5
for (int p = 0; p < 5; p++) {
max = arrSize [0][0];
index = 0;
for (int i = 0; i < arrSize.length; i++) {
for (int j = 0; j < arrSize[i].length; j++) {
if (max < arrSize[i][j]) {
max = arrSize[i][j];
index = i;
}
}
}
large[p] = max;
arrSize[index] = Integer.MIN_VALUE; //Error here
System.out.println("Highest Number: " + large[p]);
}
}
}
Error text:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Type mismatch: cannot convert from int to int[]
at secondAssignment.BiggestNumbersRectangular.main(BiggestNumbersRectangular.java:47)
I am not sure why I am getting an error, any help would appreciated. If anyone else has any answers for how I could get the top 5 in a different way that would also be appreciated.
You declare your arrSize here
int[][] arrSize = new int [4][5];
and try to set it's value here
arrSize[index] = Integer.MIN_VALUE;
The Object at arrSize[index] is an array.
Remember that a 2D array basically looks like this:
arrSize
- arrSize[0]
- arrSize[0][0]
- arrSize[0][1]
- arrSize[1]
- arrSize[1][0]
- arrSize[1][1]
- arrSize[2]
- arrSize[2][0]
- arrSize[2][1]
- arrSize[3]
- arrSize[3][0]
- arrSize[3][1]
Because index is a single int, you are assentially calling arrSize[0], which contains arrSize[0][0] and arrSize[0][1].
The Integer.MIN_VALUE is not an array of integers. It is an int. You cannot assign int to int[].
As you can see in other parts of the code, to access values in 2D array arrSize, you need 2 indexes in your case (and usually) i and j.
You need to save both i and j after you find the highest number.
if (max < arrSize[i][j]) {
max = arrSize[i][j];
indexI = i;
indexJ = j;
}
and then
arrSize[indexI][indexJ] = Integer.MIN_VALUE;
As to why you got the error, arrSize[i] gets you a 1D array. It's still an array and you cannot set an array to an integer (Integer.MIN_VALUE). in Java represented as int[] in the error message.
The algorithm could be improved, instead of using a single integer max for saving the highest value, you could use a maxArr of the same size as the number of highest numbers you want (in your case 5) and check against all of the numbers in maxArr using a for in place of
if (max < arrSize[i][j]) {
max = arrSize[i][j];
index = i;
}
That would mean you could remove the index (or indexI and indexJ) and topmost for cycle (for (int p = 0; p < 5; p++)). But that's another topic, and one you should learn yourself.

Terminated due to timeout for my hacker rank solution

Hello all please check the problemHackerRank Problem Statement
This is my solution for the above problem(link)
static int migratoryBirds(List<Integer> arr) {
int ar[]=new int[arr.size()];
for(int i=0;i<arr.size();i++){
ar[i] = Collections.frequency(arr,arr.get(i));
// ar[i] = obj.occuranceOfElement(arr,arr.get(i));
}
int maxAt = 0;
for (int i = 0; i < ar.length; i++) {
maxAt = ar[i] > ar[maxAt] ? i : maxAt;
}
return arr.get(maxAt);
}
my code is unable to handle when the array size is bigger,example 17623 elements in array.
Terminated due to timeout
The problem is in the second for loop which iterates over the array and gives me the index of the largest number in the array.Is there any other way that I could increase the performance.
Your problem is in this part:
for(int i = 0; i < arr.size(); i++)
ar[i] = Collections.frequency(arr, arr.get(i));
This is O(N²): Collections.frequency() iterates over whole list to calculate frequency for only one element. Manually, you can iterate over the list to calculate frequencey for all elements.
Moreover, ther're only 5 birds, so you need only 5 length array.
static int migratoryBirds(int[] arr) {
int max = 1;
int[] freq = new int[6];
for (int val : arr)
freq[val]++;
for (int i = 2; i < freq.length; i++)
max = freq[i] > freq[max] ? i : max;
return max;
}
Your problem is the call to Colletions.frequency, which is an O(N) operation. When you call it from inside a loop it becomes O(N²) and that consumes all your time.
Also, are you sure which implmentation of List you receive? You call list.get(i) which might also be O(N) if the implementation is a LinkedList.
The target of this exercise is to calculate the frequency of each value in one pass over the input. You need a place where you store and increase the number of occurrences for each value and you need to store the largest value of the input.
You have also skipped over a crucial part of the specification. The input has limits which makes solving the problem easier than you now think.
Here's another one:
static int migratoryBirds(List<Integer> arr) {
int freq[]=new int[6];
for(int i=0;i<arr.size();i++){
++freq[arr.get(i)];
}
int maxAt = 1;
for (int i = 2; i < freq.length; i++) {
if (freq[i] > freq[maxAt]) {
maxAt = i;
}
}
return maxAt;
}
We can determine the type number of the most common bird in one loop. This has the time complexity O(n).
static int migratoryBirds(int[] arr) {
int highestFrequency = 0;
int highestFrequencyBirdType = 0;
int[] frequencies = new int[5]; // there are 5 bird types
for (int birdType : arr) {
int frequency = ++frequencies[birdType - 1];
if (frequency > highestFrequency) {
highestFrequency = frequency;
highestFrequencyBirdType = birdType;
} else if (frequency == highestFrequency && birdType < highestFrequencyBirdType) {
highestFrequencyBirdType = birdType;
}
}
return highestFrequencyBirdType;
}
For each element in the array arr we update the overall highestFrequency and are storing the corresponding value representing the highestFrequencyBirdType . If two different bird types have the highest frequency the lower type (with the smallest ID number) is set.

Java - Unable to pass 1 dimension array to 2 dimension array

I'm trying to read a pdf file using pdfbox line by line so that i can compare it with an older version.
For this, i have done:
static String[][] SplitString_into_array(String string_to_split)
{
final int SIZE = 1495; //max size allowed in array
int number_arrays = string_to_split.length()/SIZE;
int start = 0;
int end = SIZE;
int max = string_to_split.length();
int i, j;
// Pdfs are very big, so i had to create a 2d array,
// where ROWS are the number of arrays to be created
// based on the size and COLS are the max size allowed.
String[][] pdf_final = new String[number_arrays][SIZE];
String[] pdf_split = new String[SIZE];
for(i = 0; i < pdf_final.length; i++)
{
String tmp = string_to_split.substring(start, end);
for(j = 0; j < pdf_final[i].length-1; j++)
{
pdf_split = tmp.split("\\r?\\n");
pdf_final[i][j] = pdf_split[j];
}
start = SIZE + 1;
end = SIZE + SIZE;
if(end > max)
{
end = max;
}
}
return pdf_final;
}
The problem is that i'm getting an error out of bound exception when doing:
pdf_final[i][j] = pdf_split[j];
It seems that J is only reaching the max size of I, but i have no idea why, since both sizes are defined correctly.
Can someone help me?
Regards
pdf_final[i].length can exceed pdf_split.length if your initial string is big enough. To be more exact: when string_to_split.length()/SIZE > SIZE.
Im sorry above answer is not true. It could be that i gets out of bound and not j for big files.
Like Jon Skeet said the statement doesn't give you an array of size 1495:
pdf_split = tmp.split("\\r?\\n")

Java Exam Error Checking

I have the following code from a previous past paper:
int n = arr.length;
double min = 0;
int minLocation=0;
for(int i = 1; i <= n; i++) {
if( arr[i] < min ) {
min = arr[i];
}
minLocation = i;
}
System.out.print("The minimal value is arr[");
System.out.println(minLocation + "] = " + min);
I have to answer the following questions from the code:
(i) The line on which the error appears
(ii) What effect the error would have
(iii) How the error should be corrected.
You may assume arr[] is a non-empty array of double values that has been
properly declared and initialized.
I know there will be a runtime error at the line with the if statement which i'm still not sure how. As I am unable to correct it I can't see how I get the undesired results. I can see it's such a straight forward question and I am missing out something extremely obvious but I have been looking at it for a while and i'm completely missing it.
There are several mistakes in that code. Here a list of them including explanation of impact and how to fix them:
You are initialising min with 0
Effect: If your array e.g. only consists of {1.1, 2.2} your code would claim that 0 is the minimum, what obviously is wrong because there doesn't exist an index i that arr[i] == 0
Fix: double min = Double.MAX_VALUE;
Your for-loop starts at index 1 for (int i = 1; ...)
Effect: You are skipping arr[0]
Fix: for (int i = 0 ...)
Your loop iterates once to often because of the condition or ( ... ; <= n; ...)
Effect: You will encounter an AIOOBE (ArrayIndexOutOfBoundsException)
Fix: for ( ... ; i < n; ...)
Your are overwriting minLocation in every iteration of the loop
Effect: After the last iteration of the loop, minLocation will always be = n
Fix: Place minLocation = i; inside the if-statement.
Corrected version
int n = arr.length;
double min = Double.MAX_VALUE;
int minLocation = 0;
for(int i = 0; i < n; i++) {
if(arr[i] < min) {
min = arr[i];
minLocation = i;
}
}
I know there will be a runtime error at the line with the if statement
which i'm still not sure how
This runtime error will be IndexOutOfBoundsException. This error occur because array index is one less than array size.
Your loop should be like.
for(int i = 0; i < n; i++)
Did you intend your for() loop to start at index 1? By convention it starts at 0;
It should really be: for(int i=0;i
Your for loop needs to be:
for(int i = 0; i < n; i++)
Otherwise you will get an IndexOutOfBoundsException since you access the array outside of its range.
Also you should change your min value initialiaztion to:
double min = Double.MAX_VALUE;
Otherwise you will only find the minimum if your array only contains negative values.
There are logical errors in your program, if it is intended to find the minimal value and position of given array.
Initialize
double min = arr[0];
End for loop at
i < n
Include
minLocation = i;
as
if( arr[i] < min )
{
min = arr[i];
minLocation = i;
}
Java array indices start at 0. So the for loop should be for( int i = 0; i < n; i++ ).
The minimum is only computed if the the elements of the array are non-negative.

Printing index and element of array

Hey guys I'm really struggling with trying to print my array index and element value, I posted a question a few days ago and got really helpful advice but cannot seem to get this part right at all, I am able to print the 1st index of the array (distance) but not able to print the entire thing without losing the original index value:
double minVal = Double.MAX_VALUE;
int minIndex = -1;
for (int i=0, max=distances.length; i<max;i++) {
if (distances[i] < minVal) {
minVal = distances[i];
minIndex = i;
//Gets the minimum point and minimum distance
}
}
System.out.println("The Nearest to point K is point: "+minIndex+" with distance "+minVal);
Really sorry to keep bringing this matter up but really have tried and cannot get it to work for the life of me any help or advice would be appreciated.
First, you sort
for (int i=0; i<distances.length; i++) {
for(int j = i+1; j<distances.length; j++)
{
if (distances[i] > distances[j])
{
double temp = distances[j];
distances[j] = distances[i];
distances[i] = temp;
}
}
}
Then, you merely print
for (int i=0; i<distances.length; i++) {
System.out.println(i + " -> " + distances[i]);
}
If you want to keep the original indexes, you can do that too.
the most obvious way would be to have a second paralell array, and sort that along with your original array
example:
if (distances[i] < minVal)
{
double temp = distances[j];
int tempindex = indices[j];
...
the better way would be to make a class with an index(or more appropriately named, an ID), and a value(which is your double), and sort an array of type Distance.
.
Class Distance
{
public int ID;
public double value;
}
Try change the for loop to for(int i=0; max = distances.length && i < max; i++){...}

Categories