ArrayList IndexOutOfBoundsException while processing user input - java

I am trying to write a program that uses a sentinal contolled do-while loop, that repeatedly asks the user for positive integers.
The loop should end when a negative value is entered by the user. After the loop completes, your program should print out the minimum, maximum, average, and count of the positive numbers that
were entered by the user.
However when I run the program, I get the error:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at posNeg.main(posNeg.java:31)
I have searched for answers but none of them seem to be working. Most just suggest removing the = from the for (int i = 0; i <= (count); i++) {.
Anyway, here is the full code:
import java.util.*;
import java.lang.Math;
public class posNeg {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList list = new ArrayList();
int num;
int count = 0;
do{
System.out.println("enter pos nums (or a neg num to quit): ");
num = sc.nextInt();
list.add(num);
count++;
} while (num >= 0);
Iterator it = list.iterator();
list.remove(list.get(count-1));
Object max = Collections.max(list);
Object min = Collections.min(list);
System.out.print(list);
int tot = 0;
for (int i = 0; i <= (count); i++) {
Object piece = list.get(i);
int piecenum = ((Number) piece).intValue();
tot = tot + piecenum;
}
double avg;
avg = tot/count;
System.out.println("the max is "+max+". the min is "+min+". the avg is "+avg);
}
}

When you build your list, you increment count.
So after building count==list.size().
After that you remove one item from the listbut don't change count.
So count==list.size()-1.
So your loop should be
for (int i = 0; i <= count-2; i++) {
because you have items from index 0 to count-2.
But instead of maintaining a count, you could simply do
for (int i = 0; i<list.size(); i++) {

Look at this loop:
for (int i = 0; i <= (count); i++) {
At this point the list only has count - 1 items, but you're looping count + 1 times. For the sake of sanity you should decrement count after the call to remove, and then also change the loop to the more idiomatic:
for (int i = 0; i < count; i++) {
Or, rather more simply:
for (Number number : list) {
...
}
This will only work after making list generic though:
List<Number> list = new ArrayList<Number>();
You should really be using generics for collections.

Better do it this way....
for (int i = 0; i < (count); i++) {
}
Or
Use the For-Each loop
for(Number n : list){
}

The bug is with count, as others have noted. I suggest using a conditional break; in your input loop to avoid adding the negative value to the list, and incrementing count. in the first place. You will still need to replace <= with < whenever using a language with zero based indexing.

try this list.size instead of count
for (int i = 0; i < list.size(); i++) {
Object piece = list.get(i);
int piecenum = ((Number) piece).intValue();
tot = tot + piecenum;
}

Some suggestions,,,
do{
System.out.println("enter pos nums (or a neg num to quit): ");
num = sc.nextInt();
if (num >= 0)
break;
list.add(num);
}while (true);
.. and for the next loop
int tot = 0;
for (int i : list ) {
//do your stuff
}
.. but you should really use a typed list
List<int> list = new ArrayList<int>()
... or something like that

Related

for loops and snippets where we reassign variables

The task is: write a program that swaps the maximum and minimum elements of a given array. Print the array before and after this operation.
I am still a huge noob at programming, most of the time I just can't really picture what the codes are doing.
public class problem6 {
public static void main(String[] args) {
int[] arr = new int[15];
for (int i = 0; i < arr.length; i++)
/*
I don't think I really understand incrementation in loops, what exactly do they do? As far as I understand
it is like having an industry line? I suppose 'i' would be the product and '++' would be the thing that
carries 'i' to the be checked one by one? I really need an ape analogy because I can't really visualize it.
*/
arr[i] = (int) (Math.random() * 15);
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + ", ");
System.out.println();
int minIndex = 0, maxIndex = 0; //why do we assign min and max to 0 and not any other number?
for (int i = 1; i < arr.length; i++) {
if (arr[minIndex] > arr[i])
minIndex = i;
if (arr[maxIndex] < arr[i])
maxIndex = i;
/*
I see a lot of codes like:
if (arr[minIndex] > arr[i])
minIndex = i;
if (arr[maxIndex] < arr[i])
maxIndex = i;
what purpose does it serve? For the lack of knowledge and from a really noob programmer's perspective
it seems like we are "reassigning" minIndex and maxIndex to 'i', which is probably not what we're actually doing
but I don't know how to describe it other way.
*/
}
System.out.println(minIndex + " " + arr[minIndex]);
System.out.println(maxIndex + " " + arr[maxIndex]);
{
int tmp = arr[minIndex];
arr[minIndex] = arr[maxIndex];
arr[maxIndex] = tmp;
/*
Here again, for the lack of understanding and better way of describing, it seems to me that we are reassigning,
which makes it appear illogical to me, but I'd assume it's not actually "reassigning".
int tmp = arr[minIndex];
arr[minIndex] = arr[maxIndex];
arr[maxIndex] = tmp;
*/
}
for (int i = 0; i < arr.length; i++)
System.out.print(arr[i] + ", ");
System.out.println();
}
}
What is i, what does it do and what does i++ mean:
i is used in this loop to indicate how many times you've looped through said loop.
The ++ is there to do i + 1 after each time you've looped trough the for loop.
For better understanding on how you use i in your example, imagine the array arr being a big book and what you write in the [] is which page you want to open. In the loop you basically flip through the book to each pagenumber in those brackets.
Why does minIndex and maxIndex get set to 0 instead of any other number?
They get set to 0 because we can assume that that is the lowest possible Index in your array. So when the Index gets compared to any other possible number that could be the lowest or highest Index, it always gets set to said lowest or highest Index instead of always having the same value you set because no other value in your array is higher or lower than that.
Why do we make arr[minIndex] assert the same value as arr[maxIndex]?
In your question's title you said that you wanted to swap the highest number in your array with the lowest number. So now that we have found the highest and lowest number in your array these steps switch the two.
If you have any other questions or if any of my descriptions are unclear, just comment under the answer and I'll do my best to help you out. Also, don't look down on yourself so much. Everyone was a "noob" at some point :)
Here is quick fix for you.
Following is complete example of swaps the maximum and minimum elements of a given array.
Input :
Enter elements you want to input in array:
5
Enter all the elements:
10
15
16
1
9
Output :
Element After swaps :
10
15
1
16
9
public static void main(String arg[]) {
Scanner scan = null;
int number;
try {
scan = new Scanner(System.in);
System.out.println("Enter elements you want to input in array: ");
number = scan.nextInt();
int array[] = new int[number];
System.out.println("Enter all the elements:");
for (int i = 0; i < number; i++) {
array[i] = scan.nextInt();
}
int[] resultArray = swap(array);
System.out.println("Element After swaps :");
for (int i : resultArray) {
System.out.println(i);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
scan.close();
}
}
public static int[] swap(int[] array) {
int minIndex = 0, maxIndex = 0;
for (int i = 1; i < array.length; ++i) {
if (array[i] < array[minIndex])
minIndex = i;
if (array[i] > array[maxIndex])
maxIndex = i;
}
int t;
if (maxIndex != minIndex) {
t = array[minIndex];
array[minIndex] = array[maxIndex];
array[maxIndex] = t;
}
return array;
}
Hope this solution works.
Please mark as answer if this solution is helpful.

[java]Longest consecutive integers sequence, debug

I have wrote a method for the question:
input: an array of integers
return: the length of longest consecutive integer sequence.
like: for {9,1,2,3}, return 3, cuz{1,2,3}
the method doesnt run well. hope someone could help me with debugging.
public int solution(int[] arr){
int counter = 1;
int max = arr[1];
//find the max in the array
for (int i : arr){
if (i > max){
max = i;
}
}
int[] nArr = new int[max];
for (int i : arr){
nArr[i] = i;
}
List<Integer> counters = new ArrayList<>();
for (int i = 0; i < max; i++){
if (nArr[i] == nArr[i+1] - 1){
counter++;
}else{
counters.add(counter);
counter = 1;
}
}
max = counters.get(1);
for (int i : counters){
if (i > max){
max = i;
}
}
return max; }
thanks a lot!!!
You dont need to use ArrayList... If all you want is max count of sequential integers, then try this:
int[] a = somethingBlaBla;
int counter = 0; // Stores temporary maxes
int secCounter = 0; //Stores final max
for(int j = 0; j<a.length-1; j++){ // Iterate through array
if(a[j] == a[j+1]-1){
counter++; // If match found then increment counter
if(counter > secCounter)
secCounter = counter; // If current match is greater than stored match, replace current match
}
else
counter = 0; // Reset match to accumulate new match
}
System.out.println(secCounter);
As for your method, the first thing I noticed is that max has value of greatest number in array and not the size of array. So if my array is something like {1,2,3,45,6,7,8,9}, it will throw indexOutOfBoundsException because its gonna try get 45th element in array which is not present.

Displaying odd values in an array

I am trying to display the odd numbers in an array, but only once per number (i.e. numbers[3] = 3,3,1; would only display 3 and 1 instead of 3, 3 and 1.)
this is the code that I have as of now, the program completely will create an with the specific length entered by the user and then will calculate the max min, and odd values in the array.
import java.util.Scanner;
public class ArrayLab
{
static Scanner input = new Scanner (System.in);
public static void main(String[] args)
{
System.out.println("Enter the number of numbers: ");
final int NUMBER_OF_ELEMENTS = input.nextInt();
double[] numbers = new double[NUMBER_OF_ELEMENTS];
System.out.println("Enter the numbers: ");
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
{
numbers[i] = input.nextDouble();
}
input.close();
double max = numbers[0];
double min = numbers[0];
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
{
if (numbers[i] > max)
{
max = numbers[i];
}
}
System.out.println("The max is: " + max);
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
{
if (numbers[i] < min)
{
min = numbers[i];
}
}
System.out.println("The min is: " + min);
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
{
if (numbers[i] % 2 != 0)
{
System.out.println ("The odd numbers are: " + numbers[i]);
}
}
}
}
thanks for any help.
Set<Integer> set = new HashSet<Integer>();
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
{
if (numbers[i] % 2 != 0)
{
set.add(numbers[i]);
}
}
System.out.println ("The odd numbers are: " +set);
This can be done a lot simpler using Java8:
double[] d = Arrays.toStream(numbers).filter(d -> (d % 2) == 1).distinct().toArray();
for(double tmp : d)
System.out.println(tmp);
System.out.println("min: " + Arrays.toStream(numbers).min((a , b) -> new Double(a).compareTo(b)));
System.out.println("max: " + Arrays.toStream(numbers).max((a , b) -> (new Double(a).compareTo(b))));
For you're solution: you never eliminate repeating numbers, thus the duplicates remain in the array until you print all odd numbers and the maximum-number.
This elimination can be done in several ways:
Using Java8 as above
add all values to a Set, since these don't allow duplicate values
eliminate them in your own way (i won't provide any code for this since it's rather complicated to design an efficient solution for this)
Updated solution for what you need. And Please use a better coding standard. Do note the condition check !oddNumbers.contains(numbers[i]) is not very necessary as HashSet never takes any duplicate values.
import java.util.HashSet;
import java.util.Scanner;
public class ArrayLab {
static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Enter the number of numbers: ");
final int NUMBER_OF_ELEMENTS = input.nextInt();
double[] numbers = new double[NUMBER_OF_ELEMENTS];
System.out.println("Enter the numbers: ");
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) {
numbers[i] = input.nextDouble();
}
input.close();
HashSet<Double> oddNumbers = new HashSet<Double>(NUMBER_OF_ELEMENTS);
double max = numbers[0];
double min = numbers[0];
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
if (numbers[i] < min) {
min = numbers[i];
}
if (numbers[i] % 2 != 0 && !oddNumbers.contains(numbers[i])) {
oddNumbers.add(numbers[i]);
}
}
System.out.println("The max is: " + max);
System.out.println("The min is: " + min);
System.out.println("The odd numbers are: " + oddNumbers);
}
}
A more meaningful solution to your approach would be as follows:
int[] tempArray; //temporary array to store values from your original "array"
int count=0;
for(int i=0; i<numbers.length; i++) {
if(numbers[i]%2 != 0) {
count++;
}
}
tempArray = new int[count]; //initializing array of size equals to number of odd digits in your array
int j = 0;
for(int i=0; i<numbers.length; i++) {
boolean check = true;
for(int k=0; k<j; k++) {
if(tempArray[k] == numbers[i]) {
check = false; //this will prevent duplication of odd numbers
}
}
if(numbers[i]%2 != 0 && check) {
tempArray[j]=numbers[i];
j++;
}
}
//Now print the tempArray which contains all the odd numbers without repetition
A few people have mentioned sets, but there is a different way as well. Simply sort the array, then scan through it, checking each number against the last one printed. i.e.,
int lastPrinted = 0;
// Sort the array
Arrays.sort(numbers);
System.out.print("The odd numbers are: ");
// Scan through the array
for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
{
// if it's odd and doesn't match the last one...
if (numbers[i] % 2 != 0 && numbers[i] != lastPrinted)
{
// ...print it and update lastPrinted
System.out.print( "" + numbers[i] );
lastPrinted = numbers[i];
}
}
System.out.println("");
As a side note, you really don't have to scan through the array twice to find your max and min, you can do that in one go.
I think you can use inbuilt hashmap class and its method to achieve the task without affecting the complexity of algorithm to any great extent .
import java.util.HashMap;
public class Hashing {
public static void main(String[] args) {
//declare a new hasmap
HashMap<Integer, Integer> map = new HashMap<>();
//consider Arr as your Array
int Arr[] = {3,3,1,4,5,5,7,8};
//traverse through the array
for(int i=0;i<Arr.length;i++){
//check if the required condition is true
if(Arr[i]%2==1){
/*now we insert the elements in the map but before
that we have to make sure that we don't insert duplicate values*/
if(!map.containsKey(Arr[i])){// this would not affect the complexity of Algorithm since we are using hashMap
map.put(Arr[i], Arr[i]);//We are storing the Element as KEY and as VALUE in the map
}
}
}
//now We can get these element back from map by using the following statement
Integer[] newArray = map.values().toArray(new Integer[0]);
//All the required elements are now present in newArray
for(int ele:newArray){
System.out.println(ele);
}
}
}

How Can this code be adjusted to input and print a list of numbers?

I'm trying to create a program that allows the user to input numbers into a array called "numArray", however an exception is thrown once the user inputs numbers into array. How can this be fixed?
import java.util.Scanner;
class ArrayNumList
{
public static void main(String[]args)
{
Scanner in = new Scanner(System.in);
System.out.println("How many nums would you like to enter? ");
int n = in.nextInt();
System.out.println("Enter " + n + " nums");
int[] numArray = new int[n];
for(int i = 0; i <= n; i++)
{
int index = in.nextInt();
System.out.print(numArray[index]);
}
}
}
There is no index index if the user inserts a big enough number / negative number. Fix it by using the actual loop variable i like this:
for(int i = 0; i <= n; i++) {
numArray[i] = in.nextInt();
System.out.print(numArray[i]);
}
The problem is that you aren't storing your data anywhere in the array.
for(int i = 0; i <= n; i++)
{
int index = in.nextInt();
System.out.print(numArray[index]);
}
Every time you run through the array, you store your input into the variable index. From there, you try to display the value in your array at that index. This can lead to a few problems.
1) You haven't put your numbers into this array yet, so each value in the array is going to be 0. To fix this:
numArray[i] = in.nextInt();
2) If someone inputs a number that's bigger than the size of your array, you'll get an IndexOutOfBoundsException. I don't think you were trying to do it this way, but this is what your code is currently attempting to do.
There are 3 issues:-
1) Use i < n as you start from 0
2) Trying to add input value as index in the array.
3) Printing out the values while entering which create confusion for you better to do that in separate loop but I leave it to u or Better to use println instead of print
Try this:-
public static void main(String[]args) {
Scanner in = new Scanner(System.in);
System.out.println("How many nums would you like to enter? ");
int n = in.nextInt();
System.out.println("Enter " + n + " nums");
int[] numArray = new int[n];
for(int i = 0; i < n; i++)
{
numArray[i] = in.nextInt();
System.out.println(numArray[i]);
}
}
Firstly it should be i<n and not i<=n because n means the array length and i means the array index. The index starts from 0. For eg an array holds the values 1234, so the length is 4 but the index are 0,1,2,3. So the index is always one less than the array length. Also you have to store the input with the array index.
for(int i = 0; i < n; i++)
{
numArray[i] = in.nextInt();
}
And then later print it
for(int i = 0; i < n; i++)
{
System.out.println(numArray[i]);
}

Java arrays how to save it in the array

How do I save it actually in the Array?
With this code it doesn't save anything in the array
I hope you can tell me more ways how to do it and explain in detail, thank you very much
import java.util.Scanner;
public class CountArray
{
public static void main(String[] arg)
{
Scanner scan = new Scanner(System.in);
int countPOZ = 0;
int countP5 = 0;
int countNONE = 0;
System.out.println();
System.out.print("Type elements: ");
int[] x = new int [scan.nextInt()];
for(int i = 0; i < x.length; i++)
{
System.out.print("Type numbers: ");
int numrat = scan.nextInt();
if(numrat > 0)
countPOZ++;
else if (numrat % 5 == 0)
countP5++;
else
countNONE++;
}
System.out.println();
System.out.println(x[1]); //here it will display 0 because nothing is saved.. in the array
System.out.println("Positive: "+countPOZ);
System.out.println("Div.. with 5: "+countP5);
System.out.println("Others: "+countNONE);
}
}
You store a value in the ith position of your x array with:
x[i] = someValue;
In the context of your loop :
for(int i = 0; i < x.length; i++)
{
System.out.print("Type numbers: ");
int numrat = scan.nextInt();
if(numrat > 0)
countPOZ++;
else if (numrat % 5 == 0)
countP5++;
else
countNONE++;
x[i] = numrat;
}
This stores the user's input in order.
x[i] = scan.nextInt();
Remove the local numrat and use x[i]. And please use braces, something like
x[i] = scan.nextInt();
if(x[i] > 0) {
countPOZ++;
} else if (x[i] % 5 == 0) {
countP5++;
} else {
countNONE++;
}
This is covered in and an example to JLS-10.4 - Array Access.
A component of an array is accessed by an array access expression (ยง15.13) that consists of an expression whose value is an array reference followed by an indexing expression enclosed by [ and ], as in A[i].
All arrays are 0-origin. An array with length n can be indexed by the integers 0 to n-1.
class Gauss {
public static void main(String[] args) {
int[] ia = new int[101];
for (int i = 0; i < ia.length; i++) ia[i] = i;
int sum = 0;
for (int e : ia) sum += e;
System.out.println(sum);
}
}
Try, add values in array then use array for business logic.
int[] x = new int [scan.nextInt()];
for(int i = 0; i < x.length; i++){
System.out.print("Type numbers: ");
x[i] = scan.nextInt();
if(x[i] > 0)
countPOZ++;
else if (x[i] % 5 == 0)
countP5++;
else
countNONE++;
}
But you missing something int[] x = new int [scan.nextInt()] as per your code you are not passing only one element and add that element to your array.
I assist pass multiple elements as comma separated list 1,2,3,4,5,6,7 then in your code you can create array list int x[] = scan.nextInt().split(",") then use it.
in your code
int[] x = new int [scan.nextInt()];
you are defining the size of an array. you are not storing any elements in here.
So define any elements in an array you have to access it's index and store your value in that specific index
x[1] = scan.nextInt()
can store the values in specific index

Categories

Resources