ArrayList IndexOutOfBoundsException using Scanner - java

I write a program in which the input is given by the user through scanner and if the input is even it will be added to the array list, otherwise it will be removed.
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //maximum no of elements to entered in arrayList
int a = 2;
ArrayList<Integer> al = new ArrayList<Integer>();
for(int i = 0; i < n; i++)
{
al.add(sc.nextInt());
if(al.get(i) % 2 == 0)
{
al.remove(al.get(i));
}
}
But it gives run time exception as :
Exception in thread "main" IndexOutOfBounException: Index: 2, Size:
2
TestInput:
5
1 2 3 4 5
Please tell me what I am doing wrong and other alternatives for this program!

This is happening because say you input an even number as the first number. Now as per you code you will remove this element from the list. Now the list is empty, but in the next iteration you are again trying to fetch the index of an empty list, hence the IndexOutOfBounException.
Change the logic to as follows:
First store all the numbers in the list.
for (int i = 0; i < n; i++) {
al.add(sc.nextInt());
}
Once done remove the odd numbers.
al.removeIf(i -> i % 2 != 0);
Or even better, don't store the odd numbers at all :
for (int i = 0; i < n; i++) {
int num = sc.nextInt();
if (num % 2 == 0)
al.add(num);
}

Related

How to count inputs in an array in java

I have n inputs.
these inputs are numbers from 1 to 100.
I want to output the number that appears less than the other ones; also if there are two numbers with the same amount of appearance, I want to output the number that is less than the other one.
I wrote this code but it doesn't work!
Scanner scanner = new Scanner(System.in);
int n=scanner.nextInt(), max=0 , ans=-1;
int[] counter = new int[n];
for(int i=0; i<n; i++)
counter[scanner.nextInt()]+=1;
for(int j=1; j<=100; j++){
if(counter[j]>max)
max=counter[j];
}
for (int i=1; i<=max; i++){
if(counter[i]>0)
if(ans==-1 || counter[ans]>counter[i] || (counter[ans] == counter[i] && i<ans))
ans=i;
}
System.out.print(ans);
There’s a couple of problems with your code, but the main one is the last for loop: You are trying to find the first (ie lowest) number whose counter is equal to max, so your loop should be from 1 to n, not 1 to max.
Another problem is if you are using the number, which is in the range 1-n, as your array index, you need an array of size n+1, not n.
I pinched this from another question regarding the title of yours:
i = input.nextInt (); while (i != 0) { counts [i]++; i = input.nextInt (); } That method increments the number at the position of the user input in the counts array, that way the array holds the number of times a number occurs in a specific index, e.g. counts holds how often 3 occurs.
counter array should contain frequency values for the numbers from 1 to 100 inclusive.
That is, either a shift by 1 should be used when counting the frequency:
int[] counter = new int[100];
for (int i = 0; i < n; i++) {
counter[scanner.nextInt() - 1]++;
}
or 101 may be used as the length of counter array thus representing values in the range [0..100], without shifting by 1.
int[] counter = new int[101];
for (int i = 0; i < n; i++) {
counter[scanner.nextInt()]++;
}
The minimal least frequent number can be found in a single loop (assuming that the counter length is 101).
int minFreq = 101, answer = -1;
for(int j = 1; j <= 100; j++) {
if (counter[j] > 0 && counter[j] < minFreq) { // check valid frequency > 0
minFreq = counter[j];
answer = j;
}
}
System.out.println(answer);
For a wider range of input values (e.g. including negative values) of a relatively small count it is better to use a hashmap instead of a large sparse array.

Program to find majority element of an input array doesn't work

I'm trying to find the majority element using Boyer and Moore approach. The program should ask the user to input "n" number of lines on the first line, then there will be "n" numbers followed "n" lines as input. (Ex: user input 5 on the first line, then there will be 5 numbers followed)
Next, use Boyer and Moore approach to find the majority element of an input array. If the majority element doesn't exist in the input array, then execute -1. My program output shows 0 no matter what input I entered. Would you please check it and correct my program?
Output example:
4
12
12
1
12
12
/Or: 3 11 2 13 -1
public static void main (String[]args)
{
int a[] = new int [1000000];
Scanner sc = new Scanner (System.in);
// User input n number of lines
int numberOfLine = sc.nextInt();
//Loop to have n elements as input
for (int i = 1; i<= numberOfLine; i++)
{
a[i] = sc.nextInt();
}
// Call method to display majority element
getMajorityElement(a);
sc.close();
}
//Method to Find M.E using Boyer & Moore approach
public static void getMajorityElement(int [] array)
{
int majorityElement = array[0];
int count = 1;
for (int index = 1; index<array.length; index++)
{
if(majorityElement==array[index])
{
count++;
}
else if(count==0)
{
majorityElement = array[index];
count = 1;
}
else
{
count --;
}
}
// Check if candidate M.E occur more than n/2 times
count = 0;
for (int index = 0; index<array.length; index++)
{
if(array[index]==majorityElement)
{
count++;
}
}
if (count > array.length/2)
{
System.out.println(majorityElement);
}
else
{
System.out.println("-1");
}
}
The reason you get this behavior is that your array of 1,000,000 elements has a majority element of zero: only the initial three or four items are set, while the rest of the items are occupied by zeros - the default value of an int in Java.
Fix this problem by allocating at size once the length is entered. You also need to fix the code that reads input to make sure that the data ends up at indexes 0..numberOfLine-1:
Scanner sc = new Scanner (System.in);
// User input n number of lines
int numberOfLine = sc.nextInt();
int a[] = new int [numberOfLine];
//Loop to have n elements as input
for (int i = 0 ; i < numberOfLine ; i++) {
a[i] = sc.nextInt();
}

How to print out even-numbered indexes for arrays in Java?

I'm supposed to write a program using for loops that print out the even indexes of my array. For example, if I create an array that has 10 numbers, it will have indexes from 0-9 so in that case I would print out the numbers at index 2, 4, 6 and 8. This is what I wrote so far but it doesn't work. Please note that I am not trying to print out the even numbers of the array. All I want are the even indexes.
Example I enter the following array: 3,7,5,5,5,7,7,9,9,3
Program output:
5 // (the number at index 2)
5 // (the number at index 4)
7 // (the number at index 6)
9 // (the number at index 8)
My Code:
public class Arrayevenindex
{
public static void main(String[] args)
{
int number; // variable that will represent how many elements the user wants the array to have
Scanner key = new Scanner(System.in);
System.out.println(" How many elements would you like your array to have");
number = key.nextInt();
int [] array = new int [number];
// let the user enter the values of the array.
for (int index = 0; index < number; index ++)
{
System.out.print(" Value" + (index+1) + " :");
array[index] = key.nextInt();
}
// Print out the even indexes
System.out.println("/nI am now going to print out the even indexes");
for (int index = 0; index < array.length; index ++)
{
if (array[number+1]%2==0)
System.out.print(array[number]);
}
}
}
You can just change your for loop and get rid of the inner IF...
for( int index = 0; index < array.length; index += 2) {
System.out.println(array[index]);
}
Just absolutely same thing using java 8 Stream API
Integer[] ints = {0,1,2,3,4,5,6,7,8,9};
IntStream.range(0, ints.length).filter(i -> i % 2 == 0).forEach(i -> System.out.println(ints[i]));
I assume this would be sufficient
// For loop to search array
for (int i = 0; i < array.length; i++) {
// If to validate that the index is divisible by 2
if (i % 2 == 0) {
System.out.print(array[i]);
}
}
This is what I did and it works:also I am not printing out index[0] because technically its not even thats why I started the for loop at 2. Your post did help me a lot. I also thank everyone else as well that took the time to post an answer.
import java.util.Scanner;
public class Arrayevenindex
{
public static void main(String[] args)
{
int number; // variable that will represent how many elements the user wants the array to have
Scanner key = new Scanner(System.in);
System.out.println(" How many elements would you like your array to have");
number = key.nextInt();
int [] array = new int [number];
// let the user enter the values of the array.
for ( int index = 0; index < number; index ++)
{
System.out.print(" Value" + (index+1) + " :");
array[index] = key.nextInt();
}
// Print out the even indexes
System.out.println("/nI am now going to print out the even indexes");
for ( int index = 2; index < array.length; index +=2)
{
System.out.print(array[index] + " ");
}
}
}

Finding repeats in a 2D array

I have made a program that outputs the number of repeats in a 2D array. The problem is that it outputs the same number twice.
For example: I input the numbers in the 2D array through Scanner: 10 10 9 28 29 9 1 28.
The output I get is:
Number 10 repeats 2 times.
Number 10 repeats 2 times.
Number 9 repeats 2 times.
Number 28 repeats 2 times.
Number 29 repeats 1 times.
Number 9 repeats 2 times.
Number 1 repeats 1 times.
Number 28 repeats 2 times.
I want it so it skips the number if it has already found the number of repeats for it. The output should be:
Number 10 repeats 2 times.
Number 9 repeats 2 times.
Number 28 repeats 2 times.
Number 29 repeats 1 times.
Number 1 repeats 1 times.
Here is my code:
import java.util.Scanner;
public class Repeat
{
static Scanner leopard = new Scanner(System.in);
public static void main(String [] args)
{
final int ROW = 10; //Row size
final int COL = 10; //Column size
int [][] num = new int[ROW][COL];
int size;
//Get input
size = getData(num);
//Find repeat
findRepeats(num, size);
}
public static int getData(int [][] num)
{
int input = 0, actualSize = 0; //Hold input and actualSize of array
System.out.print("Enter positive integers (-999 to stop): ");
//Ask for input
for(int i = 0; i < num.length && input != -999; i++)
{
for(int j = 0; j < num[i].length && input != -999; j++)
{
input = leopard.nextInt();
//Check if end
if(input != -999)
{
num[i][j] = input;
actualSize++;
}
}
}
System.out.println();
return actualSize;
}
public static void findRepeats(int [][] num, int size)
{
int findNum;
int total = 0, row = 0, col = 0;
for(int x = 0; x < size; x++)
{
//Set to number
findNum = num[row][col];
//Loop through whole array to find repeats
for(int i = 0; i < num.length; i++)
{
for(int j = 0; j < num[i].length; j++)
{
if(num[i][j] == findNum)
total++;
}
}
//Cycle array to set next number
if(col < num[0].length-1)
col++;
else
{
row++; //Go to next row if no more columns
col = 0; //Reset column number
}
//Display total repeats
System.out.println("Number " + findNum + " appears " + total + " times.");
total = 0;
}
}
}
I know why it is doing it, but I cannot figure out how to check if the number has already been checked for it to skip that number and go to the next number. I cannot use any classes or code that is not used in the code.
Since you cannot use anything other than this, lets say, basic elements of Java consider this:
Make another temporary 2D array with two columns (or just two separate arrays, personally I prefer this one). On the start of the algorithm the new arrays are empty.
When you take a number (any number) from the source 2D structure, first check if it is present in the first temporary array. If it is, just increment the value (count) in the second temporary array for one (+1). If it is not present in the first tmp array, add it to it and increase the count (+1) in the second at the same index as the newly added number in the first (which should be the last item of the array, basically).
This way you are building pairs of numbers in two arrays. The first array holds all your distinct values found in the 2D array, and the second one the number of appearances of the respective number from the first.
At the and of the algorithm just iterate the both arrays in parallel and you should have your school task finished. I could (and anyone) code this out but we are not really doing you a favor since this is a very typical school assignment.
It's counting the number two times, first time it appears in the code and second time when it appears in the code.
To avoid that keep a system to check if you have already checked for that number. I see you use check int array but you haven't used it anywhere in the code.
Do this,
Put the number in the check list if you have already found the count of it.
int count = 0;
check[count] = findNum;
count++;
Note: You can prefill you array with negative numbers at first in order to avoid for having numbers that user already gave you in input.
Next time in your for loop skip checking that number which you have already found a count for
for(int x = 0; x < size; x++) {
findNum = num[row][col];
if(check.containsNumber(findNUm)) { //sorry there is no such thing as contains for array, write another function here which checks if a number exists in the array
//skip the your code till the end of the first for loop, or in other words then don't run the code inside the for loop at all.
}
}
Frankly speaking I think you have just started to learn coding. Good luck! with that but this code can be improved a lot better. A piece of advice never create a situation where you have to use 3 nested for loops.
I hope that you understood my solution and you know how to do it.
All answers gives you some insight about the problem. I try to stick to your code, and add a little trick of swap. With this code you don't need to check if the number is already outputted or not. I appreciate your comments, structured approach of coding, and ask a question as clear as possible.
public static void findRepeats(int [][] num, int size)
{
int findNum;
int total = 1, row = 0, col = 0;
int [] check = new int[size];
while(row < num.length && col < num[0].length)
{
//Set to number
findNum = num[row][col];
//Cycle array to set next number
if(col < num[0].length-1)
col++;
else
{
row++; //Go to next row if no more columns
col = 0; //Reset column number
}
//Loop through whole array to find repeats
for(int i = row; i < num.length; i++)
{
for(int j = col; j < num[i].length; j++)
{
if(num[i][j] == findNum) {
total++;
//Cycle array to set next number
if(col < num[0].length-1)
col++;
else
{
row++; //Go to next row if no more columns
col = 0; //Reset column number
}
if(row < num.length - 1 && col < num[0].length -1)
num[i][j] = num[row][col];
}
}
}
//Display total repeats
System.out.println("Number " + findNum + " appears " + total + " times.");
total = 1;
}
}
you can use a HashMap to store the result. It Goes like this:
// Create a hash map
HashMap arrayRepeat = new HashMap();
// Put elements to the map
arrayRepeat.put(Number, Repeated);

Where does this program get its numbers from, and why is this caused by increasing 1 array size? (Java)

This program simply is supposed to eliminate duplicates from an array. However, the second for loop in the eliminate method was throwing an out of bounds exception. I was looking and couldnt see how that could be, so I figured I would increase the array size by 1 so that I would get it to work with the only downside being an extra 0 tacked onto the end.
To my surprise, when I increased tracker[]'s size from 10 to 11, the program prints out every number from 0 to 9 even if I dont imput most of those numbers. Where do those numbers come from, and why am I having this problem?
import java.util.*;
class nodupes
{
public static void main(String[] args)
{
int[] dataset = new int[10];
//getting the numbers
for (int i = 0; i <= 9 ; i++)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter a one digit number");
dataset[i] = input.nextInt();
}
int[] answer = (eliminateduplicates(dataset));
System.out.println(Arrays.toString(answer));
}
public static int[] eliminateduplicates(int[] numbers)
{
boolean[] tracker = new boolean[11];
int arraysize = 1;
for(int k = 0; k <= 9; k++)
{
if(tracker[numbers[k]] == false)
{
arraysize++;
tracker[numbers[k]] = true;
}
}
int[] singles = new int[arraysize];
for(int l = 0; l <= arraysize; l++)
{
if(tracker[l] == true)
{
singles[l] = l;
}
}
return singles;
}
}
The exception was occuring at this part
if(tracker[l] == true)
but only when trackers size was 10. At 11 it just prints [0,1,2,3,4,5,6,7,8,9]
EDIT: The arraysize = 1 was a hold over from debugging, originally it was at 0
EDIT: Fixed it up, but now there is a 0 at the end, even though the array should be getting completely filled.
public static int[] eliminateduplicates(int[] numbers)
{
boolean[] tracker = new boolean[10];
int arraysize = 0;
for(int k = 0; k < numbers.length; k++)
{
if(tracker[numbers[k]] == false)
{
arraysize++;
tracker[numbers[k]] = true;
}
}
int[] singles = new int[arraysize];
int counter = 0;
for(int l = 0; l < arraysize; l++)
{
if(tracker[l] == true)
{
singles[counter] = l;
counter++;
}
}
return singles;
}
Since arrays start at 0, your arraysize will be one larger than the number of unique numbers, so your final loop goes through one too many times. In other words "l" (letter l -- try using a different variable name) will get to 11 if you have 10 unique numbers and tracker only has item 0-10, thus an out of bounds exception. Try changing the declaration to
int arraysize = 0;
Once again defeated by <=
for(int l = 0; l <= arraysize; l++)
An array size of 10 means 0-9, this loop will go 0-10
For where the numbers are coming from,
singles[l] = l;
is assigning the count values into singles fields, so singles[1] is assigned 1, etc.
Edit like 20 because I should really be asleep. Realizing I probably just did your homework for you so I removed the code.
arraySize should start at 0, because you start with no numbers and begin to add to this size as you find duplicates. Assuming there was only 1 number repeated ten times, you would've created an array of size 2 to store 1 number. int arraysize = 0;
Your first for loop should loop through numbers, so it makes sense to use the length of numbers in the loop constraint. for( int i = 0; i < numbers.length; i ++)
For the second for loop: you need to traverse the entire tracker array, so might as well use the length for that (tracker.length). Fewer magic numbers is always a good thing. You also need another variables to keep track of your place in the singles array. If numbers was an array of 10 9s, then only tracker[9] would be true, but this should be placed in singles[0]. Again, bad job from me of explaining but it's hard without diagrams.
Derp derp, I feel like being nice/going to bed, so voila, the code I used (it worked the one time I tried to test it):
public static int[] eliminateduplicates(int[] numbers)
{
boolean[] tracker = new boolean[10];
int arraysize = 0;
for(int k = 0; k < numbers.length; k++)
{
if(tracker[numbers[k]] == false)
{
arraysize++;
tracker[numbers[k]] = true;
}
}
int[] singles = new int[arraysize];
for(int l = 0, count = 0; l < tracker.length; l++)
{
if(tracker[l] == true)
{
singles[count++] = l;
}
}
return singles;
}
I feel you are doing too much of processing for getting a no duplicate, if you dont have the restriction of not using Collections then you can try this
public class NoDupes {
public static void main(String[] args) {
Integer[] dataset = new Integer[10];
for (int i = 0; i < 10; i++) {
Scanner input = new Scanner(System.in);
System.out.println("Enter a one digit number");
dataset[i] = input.nextInt();
}
Integer[] arr = eliminateduplicates(dataset);
for (Integer integer : arr) {
System.out.println(integer);
}
}
public static Integer[] eliminateduplicates(Integer[] numbers) {
return new HashSet<Integer>(Arrays.asList(numbers)).toArray(new Integer[]{});
}
}
To answer your question your final loop is going one index more than the size.
The range of valid indexes in an array in Java is [0, SIZE), ie. from 0 up to arraysize-1.
The reason you're getting the exception is because in your loop you're iterating from 0 to arraysize inclusively, 1 index too far:
for(int l = 0; l <= arraysize; l++)
Therefore when you get to if(tracker[l] == true) in the last iteration, l will equal arraysize and tracker[l] will be outside the bounds of the array. You can easily fix this by changing <= to < in your for loop condition.
The reason that the problem goes away when the size of your array is changed from 10 to 11 has to do with arraysize being incremented up to 10 in the for loop above the one causing the problems. This time, singles[10] is a valid element in the array since the range of indexes in your array is now [0, 11).
EDIT: Actually arraysize has the potential to be incremented to 11, I thought it was initialised to 0 in which case it would only get to 10. Either way the above is still valid; the last index you try and access in your array must be 1 less than the length of your array in order to avoid the exception you're getting, since arrays are zero-based. So yeah, long story short, <= should be <.

Categories