Error when testing for the max value of a table? - java

I have an error when I try to run a loop that will test the max value of a table.
The table is tabl with a length of c.
int a=0;
int b=0;
while (a<=c) {
int d = tabl[a];
int e = tabl[a+1];
if(d < e)
b = e;
else
b = d;
a++;
}
It's pretty easy, it starts with comparing tabl[0] and tabl[1], and saves the bigger one, and then keeps going until a = c which is the length of the table and then finishes the loop saving the biggest value of the table in b.
But when I run this I get an java.lang.ArrayIndexOutOfBoundsException error code, can anyone help please? thanks!

When you reach a = c - 1 in your loop, your code is looking for the value of tabl[c-1]and tabl[c]. However, since your table is of length c, this causes an java.lang.ArrayIndexOutOfBoundsException. Beware that in Java, arrays are 0-indexed, that is to say, the first element is at index 0 and the last at index (length - 1).
You could write something like that, using a for-each construct :
int max = 0;
for (int element : tabl) {
if (element > max) {
max = element;
}
}
or a simple for loop
int max = 0;
for (int i = 0; i < tabl.length; i++) {
int element = tabl[i];
if (element > max) {
max = element;
}
}

The problem is you are going one past the end of the array. Arrays are zero indexed, so the item at c is going to be IndexOutOfBounds.
Also because you are accessing a + 1, this means that on the loop when a = c - 2, a + 1 will access the last element of the array.
Try:
int a=0;
int b=0;
while (a < c - 1){
int d = tabl[a];
int e = tabl[a+1];
if(d<e) { b=e;} else { b=d; }
a++;
}
NB: The change is to say a < c - 1 rather than a <= c to ensure that a is never = c when indexing into the array.

You're going out of the bounds of your array when trying to reach tabl[a+1] when a equals c
Your whole algorithm doesn't really make sense: you don't have to compare the current index's value to the next one to find out the max of the array, but rather the current value to the previous maximum value you found out.
A common way to find the maximum value of an array is that one:
int max = table[0];
for(int i = 1; i < c; i++)
if(table[i] > max)
max = table[i];
This way, max will contain the highest value of the array (though the code will throw an Exception if the table is empty).
Please, indent your code better, and use more meaningful variable names (people understand max better than b)

Related

Comparing all the characters beetween two strings(even if they contain numbers)in java

Ok so I currently have a String array which contains keycodes, and i want to check if the first element shares common specifications with the second , e.g. [012] has similar elements with [123]. I currently loop through the length of the first element, and then loop through the length of the second element, and compare those two like this:
If(A[1].charAt(j) == A[2].charAt[i]) c++; c is a counter to show how many
common elements the keycodes have. Here is the method i created
static boolean hasSimilarity(String[] A, int K, int i){
int c = 0;
for(int j = 0;j<K;j++){
for(int m = j;m<K;m++){
if(A[i].charAt(j) == A[i+1].charAt(m)) c++;
}
}
return c != 0;
}
And here is the execution of it in the Main class:
int max = -1;
findSimilar FS = new findSimilar();
for (int i = 0; i < sum.length -1; i++) {
boolean hasSimilar = FS.hasSimilarity(key,K,i);
if (!hasSimilar) {
int summ = sum[i] + sum[i + 1];
System.out.println(summ);
if (summ > max) {
max = summ;
}
}
}
When i run this, i get a java.lang.StringIndexOutOfBoundsException out of range: 0 . What am I doing wrong? Is there any better way to compare two keycodes in order to find similarities beetween them?
This error:
java.lang.StringIndexOutOfBoundsException out of range: 0
Can only occur if one of your strings is the blank string "".
You are attempting to get charAt(0) when there is no char 0 (ie first char).
——-
You would avoid this problem, and have a far more efficient algorithm, if you first collected the counts of each character then compared those, which would have time complexity O(n), whereas your algorithm is O(n2) (albeit that it seems your n - the length of your inputs - is small).

Finding Maximum Value of Array

I'm trying to loop through my array to find the maximum value and print the value. However, nothing is being printed to the console. Can you please take a look at my code below to see what I've done incorrectly.
for (c = 0; c < n; c++) //loops through array until each index has had a value input by the user
array[c] = in.nextInt();
maxInt = array[0];
minInt = array[0];
for (c = 0; c < n; c++) {
if (array[c] > maxInt) {
maxInt = array[c];
}
else {
break;
}
}
System.out.println("Max int is: " + maxInt);
}
EDIT:
Full class:
import java.util.Scanner;
public class MaxMinOfArray {
public static void main(String[] args) {
int c, n, search, array[];
int maxInt, minInt;
Scanner in = new Scanner(System.in);
System.out.println("Enter number of elements");
n = in.nextInt(); //asks user to specify array size
array = new int[n]; //creates array of specified array size
System.out.println("Enter " + n + " integers");
for (c = 0; c < n; c++) //loops through array until each index has had a value input by the user
array[c] = in.nextInt();
maxInt = array[0];
minInt = array[0];
for (c = 1; c < n; c++) {
if (array[c] > maxInt) {
maxInt = array[c];
}
}
System.out.println("Max int is: " + maxInt);
}
}
Remove:
else {
break;
}
And start from c=1
Remove your this part of code.
else {
break;
}
Because when c==0 in that time array[c] == maxInt. So it goes to else part and break your for loop.
As others indicated, you don't want to do
else {
break;
}
That means that it'll stop looping as soon as it finds a number that isn't larger than the current max. Since you're starting with the first item in the list, which trivially isn't larger than itself, you break immediately.
Even if you changed it to start at c = 1, the only case where this code could possibly work as written is if the user entered numbers in ascending order. (In that case, doing a linear search like this would be pointless anyway since you could literally just find the last item in the array and know that it'll be the largest item).
Also, you should check to see if array[c] is smaller than the current minimum value in your for loop; there's no reason at all to do this in a separate loop.
Remember, if you're doing a linear search for the max value of an unsorted array, you always must go through the entire array to make sure you didn't miss a greater value. For example, if you only search half of the array, how do you know that the half that you didn't search doesn't contain the max value?
Your second loop compares for each element in array if it is greater than maxInt, but maxInt has just been set to the first element of array. This fails the condition on the first iteration of the loop, executing the break in the else block, which ends the loop.
Taking out the else block fixes this:
for (c = 0; c < n; ++c)
{
if (array[c] > maxInt)
maxInt = array[c];
}
Or alternatively:
for (c = 0; c < n; ++c)
maxInt = Math.max(maxInt, array[c]);
As for the console message not appearing, make sure the code is properly executed by setting a breakpoint and stepping through the code (depends on the IDE you're using).

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 in arrays

hello # all i have this probleme i have two arraylist ta,ta1
ta is an 1D arraylist contain many string objects in every frame i got only one object i want to forme a new ArrayList ta1 witch take two or more object colectted from ta in n=2 case we got
1with2 2with3 3with4 ....
example i have n=2;
ta [aa,bb,cc,dd]
ta1 will be [aabb,bbcc,ccdd]
i have tried with this
String m = "";
String h = "";
int e = 0;
for (int i = 0; i <= ta.size(); i++) {
int n = Integer.parseInt(tt.getText());
while (n > 0) {
String t = (ta.get(e + i));
m = m + t;
e++;
n--;
}
ta1.add(m);
}
t3.setText(ta1.toString());
but its giving me that error in the title
tanks for your help in advance
First of all i<=ta.size() is wrong, since the valid indices of ta go from 0 to ta.size()-1.
Second of all, in your while loop you assume that e+i is a valid index in ta, which is also an assumption you can't make without testing first that e+i<ta.size().
First you should move
int n=Integer.parseInt(tt.getText());
to be before the for loop.
This way, changing
for (int i=0;i<=ta.size();i++)
to
for (int i=0;i<=ta.size()-n;i++)
will ensure that e+i<ta.size().
You should also reset the relevant variables in the correct place. I think this should work :
int n = Integer.parseInt(tt.getText());
for (int i=0;i<=ta.size()-n;i++){
int c = n;
String m = "";
int e = 0 ;
while(c>0){
String t=(ta.get(e+i));
m=m+t;
e++;
c--;
}
ta1.add(m);
}
t3.setText(ta1.toString());
for (int i=0;i<=ta.size();i++){
ArrayList is a 0 based index collection. That means that you go from 0 to size - 1. At the moment, you're going from 0 to size, which is causing the IndexOutOfBoundsException.

Where is the mistake? Finding majority

I want to find the majority in array (number that appears most of the time).
I have a sorted array and use these cycles:
for(int k = 1;k < length;k++)
{
if(arr[k-1] == arr[k])
{
count++;
if(count > max)
{
max = count;
maxnum = arr[k-1];
}
} else {
count = 0;
}
}
or
for(int h=0;h<length;h++)
{
for(int l=1;l<length;l++)
{
if(arr[h] == arr[l])
{
count++;
if(count > max)
{
max = count;
maxnum = arr[h];
}
} else count = 0;
}
}
they are similiar. When i try them on small arrays everything seems to be ok. But on a long run array with N elements 0<=N<=500000, each element K 0<=K<=10^9 they give wrong answers.
Here is solution with mistake http://ideone.com/y2gvnX. I know there are better algos to find majority but i just need to know where is my mistake.
I really can't find it :( Will really appreciate help!
First of all, you should use the first algorithm, as your array is sorted. 2nd algorithm runs through the array twice unnecessarily.
Now your first algorithm is almost correct, but it has two problems: -
The first problem is you are setting count = 0, in else part,
rather it should be set to 1. Because every element comes at least
once.
Secondly, you don't need to set max every time in your if. Just
increment count, till the if-condition is satisfied, and as soon
as condition fails, check for the current count with current
max, and reset the current max accordingly.
This way, your max will not be checked on every iteration, but only when a mismatch is found.
So, you can try out this code: -
// initialize `count = 1`, and `maxnum = Integer.MIN_VALUE`.
int count = 1;
int max = 0;
int maxnum = Integer.MIN_VALUE;
for(int k = 1;k < length;k++)
{
if(arr[k-1] == arr[k]) {
count++; // Keep on increasing count till elements are equal
} else {
// if Condition fails, check for the current count v/s current max
if (max < count) { // Move this from `if` to `else`
max = count;
maxnum = arr[k - 1];
}
count = 1; // Reset count to 1. As every value comes at least once.
}
}
Note : -
The problem with this approach is, if two numbers say - 1 and 3, comes equal number of times - which is max, then the max count will be counted for 3 (assuming that 3 comes after 1, and maxnum will contain 3 and ignore 1. But they both should be considered.
So, basically, you cannot use a for loop and maintain a count to take care of this problem.
A better way is to create a Map<Integer, Integer>, and store the count of each value in there. And then later on sort that Map on value.
Your first algorithm looks correct to me. The second one (which is what your linked code uses) needs some initialization each time through the loop. Also, the inner loop does not need to start at 1 each time; it can start at h + 1:
for(int h=0; h<length; h++)
{
count = 1; // for the element at arr[h]
for(int l=h + 1; l<length; l++)
{
if(arr[h] == arr[l])
{
count++;
}
}
if(count > max)
{
max = count;
maxnum = arr[h];
}
}
The first algorithm is much better for sorted arrays. Even for unsorted arrays, it would be cheaper to sort the array (or a copy of it) and then use the first algorithm rather than use the second.
Note that if there are ties (such as for the array [1, 1, 2, 2, 3] as per #Rohit's comment), this will find the first value (in the sort order) that has the maximum count.
The error I can readily see is that if all elements are distinct, then the max at end is 0.
However it has to be 1.
So when you update count in "else" case, update it to 1 instead of 0, as a new element has been discovered, and its count is 1.
Your first algorithm only makes sense if the array is sorted.
Your second algorithm just sets count to zero in the wrong place. You want to set count to zero before you enter the inner for loop.
for(int h=0;h<length;h++)
{
count = 0;
for(int l=0;l<length;l++)
{
if(arr[h] == arr[l])
{
count++;
if(count > max)
{
max = count;
maxnum = arr[h];
}
}
}
}
Also, you don't need to check count each time in the inner loop.
max = 0;
for(int h=0;h<length;h++)
{
count = 0;
for(int l=0;l<length;l++)
{
if(arr[h] == arr[l])
count++;
}
if(count > max)
{
max = count;
maxnum = arr[h];
}
}

Count The Amount Of Data In An Array Including SOME Null

I'm coding in java and I need to create a function that returns the number of data objects that are currently in an ArrayList. At the moment I have this:
int count = 0;
for (int i = 0; i < data.length; i++)
{
if (data[i] != null)
{
count ++;
}
}
return count;
But the problem is that an array list that includes null data is acceptable, and I have to count their null data towards this counter. How do I include the null data that's in the middle of this array, and not the null data that's not supposed to be counted for?
For example, I have some tester code that adds (8),null,null,(23),(25) to the array, and this function should return 5 when the initial array size is 10.
I'm going to assume you're using a regular array (your question is somewhat ambiguous about this). Traverse through the array backwards until you find a non-null element:
public static int count(Object[] a) {
int i = a.length - 1;
for (; i >= 0 ; i--)
if (a[i] != null)
break;
return i + 1;
}
You could also have
public static <T> int count(T[] a) {
int i = a.length - 1;
for (; i >= 0 ; i--)
if (a[i] != null)
break;
return i + 1;
}
Let's test it out, using an example analogous to the one you provided:
Object[] a = new Object[10];
a[0] = new Object();
a[3] = new Object();
a[4] = new Object();
System.out.println(count(a));
Output:
5
You will need two separate counters. The first one will count normally. The second one starts counting when you find null data. Then when you find a non-null data, just add the second counter to the first one and continue counting with the first counter until you find a null again.
int count = 0;
for (int i = data.length - 1; i >= 0; i--)
if (data[i] != null || count > 0)
count += 1;
return count;
At least that's how I understood your requirements - count nulls, except for trailing nulls.
But maybe that's not actually what you meant?
Edit
Unless you're actually using ArrayList (as Jon was asking), where .size() is different from capacity and will count all added elements (including nulls). You can't actually even get the capacity from an ArrayList.

Categories