This question already has answers here:
ArrayIndexOutOfBounds on enhanced for loop
(2 answers)
Closed 6 years ago.
I'm going through an example on Code Wars. Essentially, taking a number, finding the multiples of 3 and 5 and adding these together. Assuming the number is 10, we'll have 3,5,6,9.
I am at the point where I want to add the multiples together (the foreach loop at the bottom) but I keep getting an OutOfBoundsException. I don't understand how it is reaching index 5! Can someone please explain this to me?
I've seen a few examples of this error on here but can't checking through these I've not been able to resolve the issue, sorry.
package Test;
import java.util.ArrayList;
import java.util.List;
public class MultiplesOf3And5 {
public static void main(String[] args) {
int number = 10;
int total = 0;
List<Integer> multiples = new ArrayList<Integer>();
for (int i = 1; i < number; i++) {
if (i % 3 == 0) {
System.out.println(i + " is a multiple of 3");
multiples.add(i);
} else if (i % 5 == 0) {
System.out.println(i + " is a multiple of 5");
multiples.add(i);
}
}
for (int j : multiples){
System.out.println(multiples.get(j));
System.out.println(multiples.toString());
total += multiples.get(j);
}
System.out.println(total);
}
}
for-each loop iterates the values of your List multiples, you used each value of the List as index by accident. Fix it as below:
for (int j : multiples){
System.out.println(j);
System.out.println(multiples.toString());
total += j;
}
The output is:
3 is a multiple of 3
5 is a multiple of 5
6 is a multiple of 3
9 is a multiple of 3
3
[3, 5, 6, 9]
5
[3, 5, 6, 9]
6
[3, 5, 6, 9]
9
[3, 5, 6, 9]
23
System.out.println(j);
You are trying to get the jth object out of the list, but the you are iterating over the values not the index.
your ArrayList have = 3,6,9(factor of 3) & 5(factor of 5)
so total 4-value reside into ArrayList.
now you are trying to get value from ArrayList not based upon index like 0,1,2,3...
but you are fetching value from ArryList likewise, multiples.get(3), .get(6)... etc.
that's why you get error, like ArrayIndexOutOfBoundException.
Better to follow this way,
for (int j : multiples){
System.out.println(j);
System.out.println(multiples.toString()); // not required but you want then remain it is likewise... or else remove this line
total += j;
}
Your error is occurring because your for loop is assigning the actual values of your array list. Try this:
for(int j = 0, j < multiples.size(), j++) {
System.out.println(multiples.get(j))
}
The var j holds the current value of your iteration, not the current index of the iteration.
This should be enough :
for (int j : multiples) {
System.out.println(multiples.toString());
total += j;
}
Related
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 3 months ago.
This post was edited and submitted for review 3 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I'm not new at Java, but I'm in JUnit. I'm having a problem with a simple for loop. I'm ordering array elements with bubble sorting, but I don't know why the two last elements disappear during the loop. I know it will be a little tiny thing, but I can't find the mistake. Could you help me, please?
This is my class:
package exercise5;
public class Ejercicio5 {
public static int[] sort(int[] arrayNums) {
// array that I have tried: {6,5,8,3,7,1}; [6]
System.out.println("size: " + arrayNums.length);
for (int j = 0; j < arrayNums.length; j++) {
System.out.println("j:" + j);
if (arrayNums[j] > arrayNums[j + 1]) {
System.out.println("entra");
int numGuardado = arrayNums[j + 1];
arrayNums[j + 1] = arrayNums[j];
arrayNums[j] = numGuardado;
}
print(arrayNums);
}
return arrayNums;
}
public static void print(int[] arrayParaImprimir) {
System.out.println("Array:");
for (int j = 0; j < arrayParaImprimir.length; j++) {
if (j != arrayParaImprimir.length - 1) {
System.out.print(arrayParaImprimir[j] + ", ");
} else {
System.out.print(arrayParaImprimir[j] + "\n");
}
}
}
}
My TestClass with JUnit5:
package exercise5;
import org.junit.Assert;
import org.junit.jupiter.api.Test;
import junit.framework.TestCase;
public class Ejercicio5Test extends TestCase{
#Test
public void resultadoCorrecto(){
int[] correct = {1,3,5,6,7,8};
int[] array = {6,5,8,3,7,1};
int[] result = Ejercicio5.sort(array);
Assert.assertArrayEquals(result, correct);
}
#Test
public void resultadoIncorrecto(){
int[] correct = {1,3,5,6};
int[] array = {3,5,6,1};
int[] result = Ejercicio5.sort(array);
Assert.assertArrayEquals(result, correct);
}
}
When j is equal to 4, the ordering is doing: 5, 6, 3, 7, 1, 8
but when j passed to 5, two elements disappear.
In addition, in my Test class there are only two methods, but, when I run it, it recognises one more and give me an error:
This is the array that I have tried {1,3,5,6,7,8} and this is that I expected {5,6,3,7,1,8} with 6 of array's size, not element disappearing.
enter image description here
This is the output in console. NOT ArrayIndexOutOfBounds. Only disappear 2 elements, and the size changes, not throwing any exceptions:
size: 6
j:0
entra
Array:
5, 6, 8, 3, 7, 1
j:1
Array:
5, 6, 8, 3, 7, 1
j:2
entra
Array:
5, 6, 3, 8, 7, 1
j:3
entra
Array:
5, 6, 3, 7, 8, 1
j:4
entra
Array:
5, 6, 3, 7, 1, 8
j:5
size: 4
j:0
Array:
3, 5, 6, 1
j:1
Array:
3, 5, 6, 1
j:2
entra
Array:
3, 5, 1, 6
j:3
for (int j = 0; j < arrayNums.length; j++) {
This loops for every number in the input. Then you..
if (arrayNums[j] > arrayNums[j + 1]) {
Compare this to the next number in the input. On the last loop, you are therefore comparing the last number (arrayNums[j]) with the.. number after that. Which doesn't exist, hence, ArrayIndexOutOfBoundsEx.
You want to loop one fewer.
You missed one loop here is the correct code -
public class Ejercicio5 {
//you don't need to return as it modifies exiting array
public static void sort(int arr[])
{
int n = arr.length;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1]) {
// swap arr[j+1] and arr[j]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
/* Prints the array */
public static void printArray(int arr[])
{
int n = arr.length;
for (int i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
public static void main(String args[])
{
int[] array = {6,5,8,3,7,1};
Ejercicio5.sort(array);
System.out.println("Sorted array");
Ejercicio5.printArray(array);
}
}
output - Sorted array 1 3 5 6 7 8
and your testcases should work now with minor changes
If you run the JUnit test, it runs all the methods annotated by #Test.
Your output exactly reflects the 2 calls of your sort function, first from resultadoCorrecto() to line "j:5", second call from resultadoIncorrecto(), what outputs lines after that (from "size: 4").
So nothing has disappeared.
resultadoCorrecto() calls sort function with an array size of 6.
resultadoIncorrecto() calls sort function with an array size of 4.
Your bubble sort problem:
The for loop must go until index < length-1.
You must bubbling up all the bubbles with another for cycle around. (See Sagar Kale's answer.)
I am working on an HW assignment that asks to write a method called count that determines the number of times a target value appears in an array. For example, if your array is [2, 3, 3, 3, 4, 6, 7, 8, 8, 9], the value 8 appears twice and the number 4 appears once. You should know that the method has two parameters and one return value. The code works but the problem that I am having is when I print the statement "The value x[i] appears count(x,x[i]) times" it repeats the same statement when it should only print the statement for each value. I need help on making it so it will only print the statement as long as the value is different from the one before it if it is the same as the value before it the code should skip and move on to the next value in the array until it prints everything.
import java.util.Arrays;
public class Q7 {
public static void main(String[] args) {
int[] x = { 2, 3, 3, 3, 4, 6, 7, 8, 8, 9 };
System.out.println(Arrays.toString(x));
for (int i = 0; i < x.length; i++) {
System.out.println("The value " + x[i] + " appears " + count(x, x[i]) + " times.");
}
}
public static int count(int[] array, int target) {
int counter = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == target) {
counter++;
}
}
return counter;
}
}
Output:
[2, 3, 3, 3, 4, 6, 7, 8, 8, 9]
The value 2 appears 1 times.
The value 3 appears 3 times.
The value 3 appears 3 times.
The value 3 appears 3 times.
The value 4 appears 1 times.
The value 6 appears 1 times.
The value 7 appears 1 times.
The value 8 appears 2 times.
The value 8 appears 2 times.
The value 9 appears 1 times.
in the case of your example (because the array is sorted), you can just
change
for (int i = 0; i < x.length; i++)
to
for (int i = 0; i < x.length; i = i + count(x, x[i]))
It will skip duplicate items.
You must somehow remember for which values you have already printed the message. there are several ways to do this. For example, you could sort your array and only output the message if you hit a value you didn't have yet while iterating. Another simple approach would be to add the elements to a set to get unique values of the array. Example with a set:
public static void main(String[] args) {
int[] x = { 2, 3, 3, 3, 4, 6, 7, 8, 8, 9 };
System.out.println(Arrays.toString(x));
Set<Integer> set = new HashSet<>();
for (int i = 0; i < x.length; i++) {
if(set.add(x[i])){
System.out.println("The value " + x[i] + " appears " + count(x, x[i]) + " times.");
}
}
}
I am trying to solve the Josephus problem with an ArrayList and for loops. I have created an infinite for loop within my circle.size for loop but I cant deduce which part of my code is causing it to happen.
public class project1 {
public static int Josephus (int n, int k){
ArrayList<Integer> circle = new ArrayList<Integer>();
for (int p = 1; p <= n; p++) {
circle.add(p);
}
System.out.println("There are " + n + " people in the circle.");
System.out.println(circle);
ArrayList<Integer> kill_order = new ArrayList<Integer>();
for (int index=1; circle.size()!=1; index++){
if (circle.size() > 1){
index = (index + k - 1) % circle.size();
kill_order.add(index);
circle.remove((Integer)index);
System.out.println(kill_order);
} else if (circle.size()==1){
System.out.println("Execution Order: " + kill_order + " ");
System.out.println(kill_order);
index = 1;
}
}
return circle.get(0);
}
public static void main(String[] args) {
System.out.println("You should sit in seat " + Josephus(7, 2) + " if you want to survive!");
}
}
I think that the problem is related to this line of code circle.remove((Integer)index);
if you replace with circle.remove(index) the programs end without any infinite loop.
If you call the method circle.remove((Integer) index) it search an element inside the array with that value, the method circle.remove(index) it remove the element at the specified index.
See the javadoc for additional details remove(int index) remove(Object o)
Every next iteration of your main loop looks like:
index at the beginning of the loop
index after assign new value
circle array
1
2
1, 3, 4, 5, 6, 7
3
4
1, 3, 5, 6, 7
5
1
3, 5, 6, 7
2
3
5, 6, 7
4
2
5, 6, 7 - it cannot remove value 2 and array is not size 1
3
1
5, 6, 7
2
0
5, 6, 7
1
2
5, 6, 7
3
1
5, 6, 7 - cycle starts to repeat
So probably your algorithm is wrong, or you should remove element at index, not by value (circle.remove(index)) - without converting it to Integer
I have two arrays of different sizes that I am trying to loop through and perform calculations on, but I am ending up with incorrect outputs.
Here are the arrays:
int[] array1 = [5, 10, 2]
int[] array2 = [11, 23, 4, 6, 5, 8, 9]
int[] array1 = {5, 10, 2};
int[] array2 = {11, 23, 4, 6, 5, 8, 9};
ArrayList<Integer> calculationsArray = new ArrayList<Integer>();
int calculations = 0;
for(int i = 0; i < array1.length; i++) {
for(int j = 0; j < array2.length; j++) {
calculations = ((array1[i] + array2[j]) % 10);
}
calculationsArray.add(calculations);
}
I expect the output of [6, 3, 6, 1, 0, 8, 1]. Example calculations for 4 loops would be:
(11 + 5) % 10 = 6
(23 + 10) % 10 = 3
(4 + 2) % 10 = 6
(6 + 5) % 10 = 1
But the actual output is: [4, 9, 1]
Let's first talk about why you're seeing what you're seeing.
I've reposted your code here, with the indentation changed to reflect the nesting:
for(int i = 0; i < array1.length; i++) {
for(int j = 0; j < array2.length; j++) { // <--- This loop
calculations = ((array1[i] + array2[j]) % 10);
}
calculationsArray.add(calculations);
}
Let's take the inner loop, the one that I've marked above. Notice that on each iteration of the loop, you set calculations to a new value. This overwrites the value that was computed earlier, so that when the inner loop finishes running, the value of calculations will be equal to the last value that's computed in that loop. And that accounts for what you're actually seeing, because
when i = 0, the inner loop's last calculation is (array1[0] + array2[6]) % 10, which is (5 + 9) % 10 = 4,
when i = 1, the inner loop's last calculation is (array1[1] + array2[6]) % 10, which is (10 + 9) % 10 = 9,
when i = 2, the inner loop's last calculation is (array1[2] + array2[6]) % 10, which is (2 + 9) % 10 = 1.
And hey, look! There's your [4, 9, 1] that you're seeing.
The next question is how to go about fixing this. The major issue I believe that you're running into here is the fact that doubly-nested loops probably isn't the way to go here. Specifically, a double for loop here will run array1.length × array2.length times, which is way more than the number of times that you need it to run.
So a first question - how many times should the loop run? Well, you want your output array to have the length of the longer of the two input arrays, which is Math.max(array1.length, array2.length) times. Could you make a single loop that counts up to that number?
You then need to handle the fact that your loop may need to cycle through each input array multiple times. In the example you've given, you'll read the values of array1 multiple times because array2 is longer, but you just as easily could have had to read the values of array2 multiple times if array1 were longer.
As a hint for how to do this, see if you can use the mod operator % to wrap around when the indices get too big.
Hope this helps!
What about somenthing like (not optimized):
ArrayList<Integer> calculationsArray = new ArrayList<Integer>();
int calculations = 0;
int j = 0;
while (j < array2.size()) {
for (int i = 0; i < array1.size(); i++) {
calculations = ((array1.get(i) + array2.get(j)) % 10);
calculationsArray.add(calculations);
}
j++;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Right now I'm trying to write a function that takes an array and an integer n, and gives a list of each size n combination (so a list of int arrays). I am able to write it using n nested loops, but this only works for a specific size of subset. I can't figure out how to generalize it to work for any size of combination. I think I need to use recursion?
This is the code for all combinations of 3 elements, and I need an algorithm for any number of elements.
import java.util.List;
import java.util.ArrayList;
public class combinatorics{
public static void main(String[] args) {
List<int[]> list = new ArrayList<int[]>();
int[] arr = {1,2,3,4,5};
combinations3(arr,list);
listToString(list);
}
static void combinations3(int[] arr, List<int[]> list){
for(int i = 0; i<arr.length-2; i++)
for(int j = i+1; j<arr.length-1; j++)
for(int k = j+1; k<arr.length; k++)
list.add(new int[]{arr[i],arr[j],arr[k]});
}
private static void listToString(List<int[]> list){
for(int i = 0; i<list.size(); i++){ //iterate through list
for(int j : list.get(i)){ //iterate through array
System.out.printf("%d ",j);
}
System.out.print("\n");
}
}
}
This is a well-studied problem of generating all k-subsets, or k-combinations, which can be easily done without recursion.
The idea is to have array of size k keeping sequence of indices of elements from the input array (which are numbers from 0 to n - 1) in increasing order. (Subset then can be created by taking items by these indices from the initial array.) So we need to generate all such index sequences.
First index sequence will be [0, 1, 2, ... , k - 1], on the second step it switches to [0, 1, 2,..., k], then to [0, 1, 2, ... k + 1] and so on. The last possible sequence will be [n - k, n - k + 1, ..., n - 1].
On each step, algorithm looks for the closest to the end item which can be incremented, increments it and fills up items right to that item.
To illustrate, consider n = 7 and k = 3. First index sequence is [0, 1, 2], then [0, 1, 3] and so on... At some point we have [0, 5, 6]:
[0, 5, 6] <-- scan from the end: "6" cannot be incremented, "5" also, but "0" can be
[1, ?, ?] <-- "0" -> "1"
[1, 2, 3] <-- fill up remaining elements
next iteration:
[1, 2, 3] <-- "3" can be incremented
[1, 2, 4] <-- "3" -> "4"
Thus, [0, 5, 6] is followed by [1, 2, 3], then goes [1, 2, 4] etc.
Code:
int[] input = {10, 20, 30, 40, 50}; // input array
int k = 3; // sequence length
List<int[]> subsets = new ArrayList<>();
int[] s = new int[k]; // here we'll keep indices
// pointing to elements in input array
if (k <= input.length) {
// first index sequence: 0, 1, 2, ...
for (int i = 0; (s[i] = i) < k - 1; i++);
subsets.add(getSubset(input, s));
for(;;) {
int i;
// find position of item that can be incremented
for (i = k - 1; i >= 0 && s[i] == input.length - k + i; i--);
if (i < 0) {
break;
}
s[i]++; // increment this item
for (++i; i < k; i++) { // fill up remaining items
s[i] = s[i - 1] + 1;
}
subsets.add(getSubset(input, s));
}
}
// generate actual subset by index sequence
int[] getSubset(int[] input, int[] subset) {
int[] result = new int[subset.length];
for (int i = 0; i < subset.length; i++)
result[i] = input[subset[i]];
return result;
}
If I understood your problem correctly, this article seems to point to what you're trying to do.
To quote from the article:
Method 1 (Fix Elements and Recur)
We create a temporary array ‘data[]’ which stores all outputs one by
one. The idea is to start from first index (index = 0) in data[], one
by one fix elements at this index and recur for remaining indexes. Let
the input array be {1, 2, 3, 4, 5} and r be 3. We first fix 1 at index
0 in data[], then recur for remaining indexes, then we fix 2 at index
0 and recur. Finally, we fix 3 and recur for remaining indexes. When
number of elements in data[] becomes equal to r (size of a
combination), we print data[].
Method 2 (Include and Exclude every element)
Like the above method, We create a temporary array data[]. The idea
here is similar to Subset Sum Problem. We one by one consider every
element of input array, and recur for two cases:
The element is included in current combination (We put the element in data[] and increment next available index in data[])
The element is excluded in current combination (We do not put the element and do not change index)
When number of elements in data[] become equal to r (size of a
combination), we print it.