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.)
my output is
4 4 8 7
3 3 3 5 6 3 3 4 5
when it should be
4 4 5
8 7 7
3 3 3 4
5 6 3 1
3 4 5 6
i need to use same method for all of arrays, summing up arrays of two matrices.
how can i do that when arrays are different length and how can i print output correctly?
public static void main(String[] args) {
int[][] m1 = { { 1, 2, 0 }, { 2, 3, 4 } };
int[][] m2 = { { 3, 2, 5 }, { 6, 4, 3 } };
int[][] m3 = { { 1, 1, 1, 1 }, { 3, 3, 2, 1 }, { 2, 2, 2, 2 } };
int[][] m4 = { { 2, 2, 2, 3 }, { 2, 3, 1, 0 }, { 1, 2, 3, 4 } };
printMatrixSum(m1, m2);
System.out.println();
printMatrixSum(m3, m4);
}
private static void printMatrixSum(int[][] x, int[][] y) {
int c[][] = new int[4][4];
for (int i=0; i < 2; ++i) {
for(int j=0;j<3;j++) {
c[i][j]=x[i][j]+y[i][j];
System.out.print(c[i][j]+" ");
}
}System.out.println();
}
}
Your code is close to working. I made some changes below, and it now produces this output:
4 4 5
8 7 7
3 3 3 4
5 6 3 1
3 4 5 6
Here's the code:
1. private static void printMatrixSum(int[][] x, int[][] y) {
2. int[][] c = new int[x.length][x[0].length];
3. for (int i = 0; i < x.length; i++) {
4. for (int j = 0; j < x[0].length; j++) {
5. c[i][j] = x[i][j] + y[i][j];
6. System.out.print(c[i][j] + " ");
7. }
8. System.out.println();
9. }
10. }
Here are the edits I made:
line 2: change int c[][] to int[][] c – this is minor, but follows Java style
line 2: change new int[4][4] to use actual values for array length. The first dimension is just x.length, and the second is x[0].length. This will work correctly with different array inputs vs. hard-coding to "4".
line 3: change i < 2 condition to use the length of one of the input arrays; I chose x but it could be y (and of course this code assumes that x and y are matching dimensions)
line 3: change ++i to i++ – not sure why you were using pre-increment, but in my opinion that makes it harder to reason about loop behavior, and also the second loop (line 4) was already doing post-increment (j++) so I edited this one to make it both clearer as well as consistent with the rest of your code.
line 4: change j < 3 to be dynamic, similar to edit on line 3
line 8: move the println() here, so that a newline is printed after each row of the array is printed
Instead of printing it with fixed sizes ( like i < 2 and j <3 ), use the dimension of the array to make your function more reusable.
ii) Secondly, the println() should be outside the inner loop but inside the outer loop .
private static void printMatrixSum(int[][] x, int[][] y) {
int c[][] = new int[4][4];
for (int i = 0; i < x.length; ++i) {
for (int j = 0; j < y[0].length; j++) {
c[i][j] = x[i][j] + y[i][j];
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
and this is the answer :
4 4 5
8 7 7
3 3 3 4
5 6 3 1
3 4 5 6
A couple suggestions.
Consider not writing a printMatrixSum method. Write a method to print a matrix. You may not always want to print a matrix after you compute the sum. Of course that means iterating over the matrix twice so it's ultimately going to be based on your requirements.
specify a width value to help nicely format the output.
And you don't need to index the matrix. Multi-dimensional arrays are simply arrays of other arrays. So you can use the enhanced forloop to first iterate the rows, and then the values in each row.
Here is an example.
int [][] data = {{203,2,3334,-22022, 23},{2,1,233, 42,33}};
matPrint(data, 7);
prints
203 2 3334 -22022 23
2 1 233 42 33
use the width to specify the largest value(including sign)
create a format for System.out.printf
then simply iterate the rows. and within each row, iterate the values.
public static void matPrint(int[][] m, int width) {
String fmt = "%" + width + "s";
for (int[] row : m) {
for (int col : row) {
System.out.printf(fmt, col);
}
System.out.println();
}
}
If you have a specific width that you want to use often you can overload the print method as follows. Then you can use the one argument version which invokes the two argument with the default width.
private static int DEFAULT_WIDTH = 4;
public static void matPrint(int[][] m) {
matPrint(m, DEFAULT_WIDTH);
}
And if you specify the field width as a negative value, it will left justify the output within each field.
question:
Suppose this is the number in my array {1,2,3,4,5,6,7,8}
and each number is a position like ::
1=1 ,2=2 , 3=3, 4=4, 5=5, 6=6, 7=7, 8=8
It is not an array position just the number position. Now i want to remove the number in odd position then it becomes
2,4,6,8 :: 2=1, 4=2, 6=3, 8=4,
Now again i want to remove from the odd position so it becomes 4,8 :: 4=1, 8=2
Now the answer is 8 so how to get this 8
Code:
int [] arr = new int [] {1, 2, 3, 4, 5, 6, 7, 8}; //I am taking certain number in array
System.out.println("Elements of given array present on even position:");
for (int i = 1; i < arr.length; i = i+2) {
System.out.println(arr[i]);
}
must get the value as 8 but in output i get:
2
2
2
2
4
4
4
4
and so on
This will print out even numbers:
for (int i = 0; i < arr.length; i++)
{
if (arr[i] % 2 == 0)
{
System.out.println(arr[i]);
}
}
If you want to remove the odd position elements from the array, then make a new one and use the above code to exclude odd elements like so:
ArrayList<Integer> newArr = new ArrayList<>();
for (int i = 0; i < arr.length; i++)
{
if (i % 2 == 0)
{
newArr.add(arr[i]);
}
}
As I said in my comment, you want the greatest power of 2 :
int max=0;
for (int i=0;i<arr.length;i++) {
int pos = arr[i];
if((pos & (pos-1)) == 0) { // check if pos is a power of 2
max =java.lang.Math.max(max, pos);
}
}
System.out.println(max)
if arr = {1,2,3,4,5,6,7,8}; => output 8
if arr = {1,2,3,4,5,6,7,8,9} => output 8
if arr = {1,2,3,...,20} => output 16
You could use an ArrayList
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0; i<arr.length; i++){
if(i % 2 == 0){ //if divide by 2 gives remainder 0 it is even
list.add(arr[i]);
}
}
arr=list.toArray();//get the array version of the list
Then you could put it in a while loop to do it until there is only one left.
int [] arr = new int [] {1, 2, 3, 4, 5, 6, 7, 8};
while(arr.length>1){
...
}
System.out.println(arr[0]);
Remember that we start counting at 0 so the first position(i=0) would even and the second position(i=1) would be uneven.
Final Code:
int [] arr = new int [] {1, 2, 3, 4, 5, 6, 7, 8};
while(arr.length>1){
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0; i<arr.length; i++){
if(i % 2 == 0){ //if divide by 2 gives remainder 0 it is even
list.add(arr[i]);
}
}
arr=list.toArray();//get the array version of the list
}
System.out.println(arr[0]);
This should do it for you
int [] arr = new int [] {1, 2, 3, 4, 5, 6, 7, 10, 11, 12}; //I am taking certain
System.out.println("Elements of given array present on even position:");
int counter=2;
while(counter<=arr.length){
counter*=2;
}
System.out.println(arr[(counter/2)-1]);
Let me know if this works
I am developing a numerology application which has to provide a result which is similar to the following,
1 5 0 8 1 9 9 4
6 5 8 9 1 1 1
1 1 1 1 2 2
2 2 2 3 4
4 4 5 7
8 9 1
1 1
2
It has to add the consecutive digits and retain the first digit if the sum is of 2 digits.
I am missing something. Adding a while loop for the length of intList doesn't seem to work.
int date;
List<Integer> sumList = new ArrayList<Integer>();
Scanner s = new Scanner(System.in);
System.out.println("Enter the date");
date = s.nextInt();
int len = Integer.toString(date).length();
int[] convertarray = new int[len];
for (int index = 0; index < len; index++) {
convertarray[index] = date % 10;
date /= 10;
}
List<Integer> intList = new ArrayList<Integer>();
for (int i : convertarray) {
intList.add(i);
}
Collections.reverse(intList);
System.out.println(intList);
int sum = 0;
int size = intList.size();
for (int i = 0; i < intList.size() - 1; i++) {
sum = intList.get(i) + intList.get(i + 1);
int length = (int) (Math.log10(sum) + 1);
if (length > 1) {
int firstDigit = Integer.parseInt(Integer.toString(sum).substring(0, 1));
sum = firstDigit;
}
System.out.print(sum + " ");
sumList.add(sum);
}
System.out.println("\n");
intList.clear();
intList = sumList;
My output is something like,
1 5 0 8 1 9 9 4
6 5 8 9 1 1 1
A simple recursive solution:
public static void main(String[] args) throws Exception {
String birthday = "01091995";
int[] digits = Arrays.stream(birthday.split("")).mapToInt(Integer::parseInt).toArray();
recursiveFunction(digits);
}
private static void recursiveFunction(int[] digits) {
if(digits.length == 1) {
// Base Case
System.out.println(digits[0]);
} else {
// Recursive Case
System.out.println(Arrays.toString(digits));
int[] digitsProcessed = new int[digits.length -1];
for (int i = 0; i < digits.length - 1; i++) {
digitsProcessed[i] = digits[i] + digits[i+1]; // Logic
}
recursiveFunction(digitsProcessed);
}
}
This produces:
[0, 1, 0, 9, 1, 9, 9, 5] // 8 numbers
[1, 1, 9, 10, 10, 18, 14] // 7 numbers
[2, 10, 19, 20, 28, 32] // 6 numbers
[12, 29, 39, 48, 60] // 5 numbers
[41, 68, 87, 108] // 4 numbers
[109, 155, 195] // 3 numbers
[264, 350] // 2 numbers
614 // 1 number
Adding a while loop for the length of intList doesn't seem to work.
Well it can be done with loops, but it would be harder and messier.
An algorithm with recursion would be the following:
Init the array of integers.
Call the recursive function "F" with the array.
From now, the recursive function behaviour:
Check if the recieved array's length is 1.
If it is, print the element and terminate.
If it is not:
Print the recieved array.
Make a new array.
Put in this new array the result of processing the recieved one adding as intended.
Call the recursive function "F" with this new array.
I am a newbie to programming. I am trying to create a program that would display an array in reverse. Plus also find the even and odd numbers of an array,sum the count and also display the even and odd numbers. The code works but the problem is that it also reverses the even and odd arrays and it shows this weird zero in those arrays. What am I doing wrong?
Please also provide explanation. Thanks!
import java.util.Arrays;
public class ArrayTest {
public static void main(String[] args)
{
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12,13};
for ( int i=0; i<array.length/2; i++ )
{
int temp = array[i];
array[i] = array[array.length-(1+i)];
array[array.length-(1+i)] = temp;
}
System.out.println("Array after reverse: \n" + Arrays.toString(array));
int even=0;
int odd=0;
int[] Even = new int[13];
int[] Odd = new int[13];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[i] = array[i];
even++;
}
else
{
Odd[i] = array[i];
odd++;
}
}
System.out.println("Even: "+even+" ");
System.out.println(Arrays.toString(Even));
System.out.println("Odd: "+odd+" ");
System.out.println(Arrays.toString(Odd));
}
}
The output is:
Array after reverse:
[13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Even: 6
[0, 12, 0, 10, 0, 8, 0, 6, 0, 4, 0, 2, 0]
Odd: 7
[13, 0, 11, 0, 9, 0, 7, 0, 5, 0, 3, 0, 1]
You need to correct your logic
int[] Even = new int[(array.length/2)+1];
int[] Odd = new int[(array.length/2)+1];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[even] = array[i];
even++;
}
else
{
Odd[odd] = array[i];
odd++;
}
}
As per you code, you are initializing array of size 13 for odd and even, which is not correct.
int[] Even = new int[13];
int[] Odd = new int[13];
So, by default, Even and Odd array will be initialized by 0 value. Then, you are setting value as per main array, which a size of 13 on alternate basis (even/odd).
==Updated==
Since, you don't want Even and Odd array in reverse order. Then, you can move the code up.
>>Demo<<
You faced 2 problems (I guess so)
The odd and even arrays are also in reverse order
Reason: The first For loop reverses the 'array' and stores the results in array itself. So, the next time when you try working with 'array' to find odd/even numbers, you are actually working with the reversed array.
Solution: You can assign the original array to a backup array and use that backup array to find odd and even nos.
Unnecessary zeros:
Reason: In your second for loop you used odd[i]=array[i] which seems to be a logical error in your code. Consider the case:
value of i : 0 1 2 3 4 5 ... 12
value of array[i]: 1 2 3 4 5 6 ... 13
value of odd[i] : 1 0 3 0 5 0 ... 13
value of even[i] : 0 2 0 4 0 6 ... 0
This means, the control inside for loop is made to flow either to if{} block or the else{} block and not the both. So, when if(condition) is satisfied, then even[i] array will be updated. But meanwhile what happens to the odd[i] array? It retains the inital value '0'. That's it!
I hope the following code helps you:
import java.util.Arrays;
public class A
{
public static void main(String[] args)
{
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int[] arr2 = new int[array.length]; // backup array
arr2=Arrays.copyOfRange(array,0,array.length);
for ( int i=0; i<arr2.length/2; i++ )
{
int temp = arr2[i];
arr2[i] = arr2[arr2.length-(1+i)];
arr2[arr2.length-(1+i)] = temp;
}
System.out.println("Array after reverse: \n" + Arrays.toString(arr2));
int even=0;
int odd=0;
int[] Even = new int[13];
int[] Odd = new int[13];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[even] = array[i];
even++;
}
else
{
Odd[odd] = array[i];
odd++;
}
}
Even=Arrays.copyOfRange(Even,0,even);
Odd=Arrays.copyOfRange(Odd,0,odd);
System.out.println("Even: "+even+" ");
System.out.println(Arrays.toString(Even));
System.out.println("Odd: "+odd+" ");
System.out.println(Arrays.toString(Odd));
}
}
Note: I have used Arrays.copyOfRange(array,start,end) function to copy a certain part of the array from start to end-1 position.
Output:
Array after reverse:
[13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Even: 6
[2, 4, 6, 8, 10, 12]
Odd: 7
[1, 3, 5, 7, 9, 11, 13]
Hope this helps :)
--Mathan Madhav
You select even and odd numbers from reversed array.
You use wrong index for even and odd arrays.
If you don't want to see zeros in output, use print in for statement. Another solution - firstly count odd and even numbers and create arrays with exact size.
import java.util.Arrays;
public class ArrayTest {
public static void main(String[] args)
{
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int even=0;
int odd=0;
int[] Even = new int[13];
int[] Odd = new int[13];
for ( int i=0; i<array.length; i++)
{
if (array[i] % 2 == 0)
{
Even[even++] = array[i];
}
else
{
Odd[odd++] = array[i];
}
}
for ( int i=0; i<array.length/2; i++ )
{
int temp = array[i];
array[i] = array[array.length-(1+i)];
array[array.length-(1+i)] = temp;
}
System.out.println("Array after reverse: \n" + Arrays.toString(array));
System.out.println("Even: "+even+" ");
System.out.println(Arrays.toString(Even));
System.out.println("Odd: "+odd+" ");
System.out.println(Arrays.toString(Odd));
}
}