Indexing in java arrays - java

I had to write a method in Java, where having in input an array a of numbers and a number x returns an array of elements which follows the last occurrence of x in a.
For example with input {0,1,2,3,4,5,6,7,8,9} and x=6 the method must return {7,8,9} meanwhile with {4,1,4,2} and x=4 the method must return {2} and if the x is not in a then it must return empty array {} (or array with 0 length)
so I got this answer:
int idx = -1;
for (int i = 0; i < s.length; i++) {
if (s[i] == x)
idx = i;
}
/* After you found this index, create a new array starting
* from this element. It can be done with a second (not nested) for loop, or you can
* use Arrays.copyOfRange()
*/
//make sure idx != -1
int[] t = new int[s.length - idx - 1];
for (int i = idx + 1; i < s.length; i++)
t[i - idx - 1] = s[i];
which was very helpful but I could not understand why this works:(EDITED; Ok now I understand why this works but even if in my opinion the combined for loop ideea was more less complicated to read)
t[i - idx - 1] = s[i];
and this doesn't:
int[] t = new int[a.length - indx - 1];
for (int j = indx + 1; j < a.length; j++) {
for (int i = 0; i < t.length; i++) {
t[i]=a[j];
}
}
return t;
EDITED :
To clarify this is all the code
int[] dopoX(int[] a, int x) {
int n = a.length;
int[] c = new int[0];
int indx = 0;
int nrx = 0;
for (int j = 0; j < a.length; j++) {
if (a[j] == x)
nrx++;
if (a[j] == x)
indx=j;
}
if (nrx == 0)
return c;
int[] t = new int[n - indx - 1];
for (int j = indx + 1; j < n; j++) {
for (int i = 0; i < t.length; i++) {
t[i] = a[j]; /* it returns just 1 number of a[] like t{2,2,2,2,2,2,2,2} which is
not correct */
}
}
return t;
}

Well you want to copy all the remaining values, and create an array of index t. Thus you need to start with i=0. You can however perform a shift-operation: increase i somewhere, and when you use it, shift it back, so:
for (int i = idx+1; i < s.length; i++)
t[i-idx-1] = s[i];
is equvalent to:
for (int i = 0; i < t.length; i++)
t[i] = s[i+idx+1];
(which would have been more readable as well)
About your second question:
here you use a nested loop: the second for loop will be repeated each iteration of the first one.
The result is thus that in the second for-loop, j is always fixed, with input {1,2,...,9} and 6 in the first iteration, you would fill your array with 7s, next 8s and finally 9s.
You can however use a combined for loop:
int []t=new int[n-indx-1];
// /-- grouped initializers /-- grouped increments
// | |
for(int i=0, j= indx+1; i < t.length; i++, j++){
t[i]=a[j];
}
return t;

Let's suppose you take the case where a[] = {1,2,3,4,5,6,7,8,9} and x = 6.
Running this:
int idx = -1;
for (int i = 0; i < s.length; i++) {
if (s[i] == x) idx = i;
}
You got idx = 5 as s[5] == x.
Now we want to copy the array after the last instance of x into a new array t[].
Obviously, you have to start from the index idx + 1 as idx contained the last occurance of x.
Hence, this code:
int[] t = new int[s.length - idx - 1];
for (int i = idx+1; i < s.length; i++)
t[i-idx-1] = s[i];
What do you do here?
You construct a new array t[] having length s.length - idx - 1, in our case s.length = 9 and idx = 5 hence, we have the s.length - idx - 1 as 3 and we can check that is the number of elements after x = 6.
Now, we start the iterator i from idx + 1 (Reason explained above) to s.length
We have t[i - idx - 1] because when i = idx + 1, i - idx - 1 = 0. Hence as i increases, your i - idx - 1 also increases.
Hope it was convincing. Please comment if you still have any doubts.

The first line of code finds the last index of x inside of the array.
The second line uses the built-in function of Arrays to copy a range from an array to a new copy.
And we copy from the values after the last x until lenght of array a.
The first line could be rewritten to search from the end and backwards in the array with a break. This will give a performance boost but makes the code less easy to read.
for(int i=0; i<a.length;i++) if(a[i]==x) idx=i;
int[] b = Arrays.copyRangeTo(a, idx+1, a.length);

Try this:
int j=0;
int i=idx+1;
while (j<t.length) {
t[j] = s[i];
j++;
i++;
}

Related

Removing a number from array in Java

I would like to remove a particular number from the array
Integer[] arr = new Integer[7];
for (int i = 0; i < arr.length; i++) {
arr[i] = i;
}
Collections.shuffle(Arrays.asList(arr));
This is creating numbers from 0-7
But I dont need 0,I need value from 1-7
The first value written into your array is 0 because you initialize i with 0 in the for loop.
Therefore your loop will only insert the values 0 - 6.
Change this initialisation to i = 1 and in addition you also need to change the condition of the for loop to arr.length + 1 or i <= arr.length, so it will count up to 7.
Integer[] arr = new Integer[7];
for (int i = 1; i < arr.length + 1; i++) {
arr[i] = i;
}
What you also can do instead of changing the loop itself, is to change the loop body. Just add 1 to i when assigning it to arr[i]:
for (int i = 0; i < arr.length; i++) {
arr[i] = i + 1;
}
In this case i will count from 0 to 6, and assign 1 to 7 to your array
Change your int i = 0 to int i = 1 like this:
Integer[] arr = new Integer[7];
for(int i = 1; i <8; i++){
int value = i-1;
arr[value] = i;
}
Collections.shuffle(Arrays.asList(arr));
for(int i = 0; i < arr.length; i++){
System.out.println("Result:"+arr[i]);
}
Console message:
Result:7
Result:2
Result:6
Result:5
Result:4
Result:1
Result:3

How to understand Loops and Array in java

I am quite confused in array loops that do have nested ones to print the Two Dimensional array. /it contains a loop without curly braces and second one has just opposite way of representing the braces for loops ...
Since i am learning I have just typed the code and got output.
public class TwoDimensional {
private int i, j, k = 0;
int[][] twod = new int[4][5];
public void DoubleT() {
for (i = 0; i < 4; i++)
for (j = 0; j < 5; j++) {
twod[i][j] = k;
k++;
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 5; j++)
System.out.print(twod[i][j] + " ");
System.out.println();
}
}
}
The result it generates is
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
Try this :
public class TwoDimensional {
private int i, j, k = 0;
int[][] twod = new int[4][5];
public void DoubleT() {
for (i = 0; i < 4; i++)
for (j = 0; j < 5; j++) {
twod[i][j] = k;
k++;
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 5; j++){
System.out.print(twod[i][j] + " ");
}
System.out.println();
}
}
To properly use the braces always think about the purpose of the loops you have, when do you want them to finish and when do you want them to continue.
In your case, you'll need nested loops for different tasks so you have to properly delimit each one of those tasks.
Fill the the 2D array:
for (i = 0; i < 4; i++)
for (j = 0; j < 5; j++) {
twod[i][j] = k;
k++;
}
}
Print the 2D array values:
for (i = 0; i < 4; i++) {
for (j = 0; j < 5; j++){
System.out.print(twod[i][j] + " ");
}
System.out.println();
}
Notice that, either for filling or printing the array, your first loop (iterator i) is responsible for the line. It'll stop at I = 3, line number 3. So you'll be in line 0 until you finish the values of all the columns on that line ( [0][0],[0][1],[0][2],[0][4] ) and you just want to go to the second line when your first line is totally filled or printed, and so on. On the print case, you'll need to change the line before the 'i' increments (new line number) and after you have all `'j' values.
To summarize, you'll just want to increment the line ('i') or go to the next line (println()), when your columns ('j') are finished.

Create a 2d array from an ArrayList<Integer>

I have an ArrayList and I want to create a method that will turn it into a 2d array, int[][].
This new 2d array will represent a matrix and it has to be square, so for example if I use [8, 2, 3, 0] the ressult will be {8,2}
{3,0}
public static int[][] convertIntegers(ArrayList<Integer> integers){
int m = (int) Math.sqrt(integers.size());
int[][] ret = new int[m][m];
int cont = 0;
for(int i=0; i<m+1 ; i++)
{
for(int j=0; j<m; j++)
{
cont = cont + 1;
ret[i][j] = integers.get(cont);
;
}
}
return ret;}
Your implementation is almost ok, except for some off-by-one errors:
You need to increment cont after the integers.get call, not before. If you increment before, then the first element of the list will be skipped. An easy way to fix that is to move the incrementing inside the inner loop, counting it together with j.
The outer loop should go until i < m instead of i < m + 1
With the errors fixed:
for (int i = 0, cont = 0; i < m; i++) {
for (int j = 0; j < m; j++, cont++) {
ret[i][j] = integers.get(cont);
}
}
Btw, another way is without using cont at all,
calculating the correct position using i, j and m:
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
ret[i][j] = integers.get(i * m + j);
}
}

ArrayIndexoutofbound exception merging two sorted array

I have seen other solutions like this and wondering if there is anything wrong with my approach of using for loop. I don't want to use while loop as others have used in their solution.
package com.my.practice;
public class MedianOfTwoArrays {
public static void main(String[] args) {
// Given two sorted arrays of same size
int[] a1 = {1,2,3,4,5,6};
int[] a2 = {7,8,9,10,11,12};
int[] mergedArray = new int[a1.length + a2.length];
for(int i=0 ; i < a1.length; i++){
mergedArray[i] = a1[i];
}
//System.out.println("Length:"+2*(a1.length));
for(int i= a1.length; i < 2 * (a1.length); i++) {
mergedArray[i] = a2[i];
}
for(int i=0 ; i < 2*(a1.length); i++){
System.out.println("Part of Array: "+mergedArray[i]+ " Length is: "+mergedArray.length);
}
}
}
I am getting following error :
Length:12
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at com.my.practice.MedianOfTwoArrays.main(MedianOfTwoArrays.java:30)
In this line:
for (int i= a1.length; i < 2 * (a1.length); i++) {
mergedArray[i] = a2[i];
}
you are trying to access a2[i] for i from 6 to 11. Since a2 is an array of size 6, a2[6], a2[7] ... a2[11] do not exist.
In your case, you want to insert values a2[1] into mergedArray[6], a2[2] into mergedArray[7] etc.
You either need to substract a1.length on the right side:
for (int i = a1.length; i < 2 * (a1.length); i++) {
mergedArray[i] = a2[i - a1.length];
}
or add a1.length on the left side:
for (int i = 0; i < a1.length; i++) {
mergedArray[i + a1.length] = a2[i];
}
Choose the more convenient one.
Mistake (for ArrayOutOfBoundException):
for(int i= a1.length; i < 2 * (a1.length); i++) {
mergedArray[i] = a2[i]; //Using 'i' incorrectly to access a2[i]
}
Correcting above:
for(int i= 0; i < a2.length; i++) {
mergedArray[i+a1.length] = a2[i]; //Using 'i' incorrectly to access a2[i]
}
Reasons:
'i' here will ensure that a2 is not exceeded beyond its size because i's max limit is a2.length.
Do not assume that a2 and a1's size would be equal. While traversing a1 using a1.length and while traversing a2, use a2.length.
A safety (redundant) check can be added to ensure that (i+a1.length) does not exceed mergedArray size. Redundant in this case because the mergedArray's length = a1.size + a2.size.
Problem is your are using same index for arrays of different length:
for(int i= a1.length; i < 2 * (a1.length); i++)
mergedArray[i] = a2[i];
Here at initial, i = 6, array bounds for a2 is 0-5 however a2[i] is a2[6], out of bounds, which gives you the exception.
You can skip those loops, by using System.arraycopy()
System.arraycopy(a1, 0, mergedArray,0, a1.length);
System.arraycopy(a2, 0, mergedArray,a1.length, a2.length);
If you still wana use loop, simply use another index variable:
for(int i = 0, j = a1.length; i < (a2.length); i++, j++)
mergedArray[j] = a2[i];
The issue in your code is due to using i as an index for a2 in second loop. Its valid for mergedArray but not for a2
Either use i-a1.length as index in your second loop
for(int i= a1.length; i < 2 * (a1.length); i++) {
mergedArray[i] = a2[i-a1.length];
}
Or use three indices: i, j & k. Just to give you an idea
int i, j, k = 0;
for (i = 0; i<a1.length; i++){
mergedArray[k] = a1[i];
k++;
}
for (j=0; j<a2.length; j++){
mergedArray[k] = a2[j];
k++;
}
It's not a good idea to rely on the two arrays having the same length, so I wouldn't use a1.length * 2. In addition, you can't use the same index for the original arrays and the merged array, since the merged array is longer.
A suggested fix:
int[] mergedArray = new int[a1.length + a2.length];
for(int i=0 ; i < a1.length; i++){
mergedArray[i] = a1[i];
}
for(int i= 0 ; i < a2.length; i++){
mergedArray[a1.length + i] = a2[i];
}
for(int i=0 ; i < mergedArray.length; i++){
System.out.println("Part of Array: "+mergedArray[i]+ " Length is: "+mergedArray.length);
}

Java: Generating a custom sets of elements

I need a simple java program that can generate me the custom sets for a set,say for {'1','2','3','4'}. The result should be:
{'1','2'},{'2','3'},{'3','4'},{'1','2','3'},{'2','3','4'}.
I have tried codes for powerset,but the output isn't desirable. It would be appreciable if the code could be something like:
for(j=2;j<set.size()-1;j++)
{
for(i=0;i<set.size()-1;i++)
{
//a[i],a[i+1] when j=2
//a[i],a[i+1],a[i+2] when j=3
}
}
I know .size() is for ArrayList and a[i] is for simple array and i've written both as any approach will do!! Thanks In Advance!! :)
This code should print the values you want:
final int[] values = {1, 2, 3, 4};
for (int size = 2; size < values.length; size++) {
for (int i = 0; i + size <= values.length; i++) {
for (int j = 0; j <= size - 1; j++) {
System.out.print(values[i + j]);
}
System.out.println();
}
}
From the example, we see that you want to print sets of values whose length is greater than 1 and smaller than the total set, so that 's what the following line does:
for (int size = 2; size < values.length; size++) {
After that we compute the starting index of the subset, watching not to run into a IndexArrayOutOfBounds exception (see the line below)
for (int i = 0; i + size <= values.length; i++) {
From there we just print the values starting at i index and with the subset length of size
for (int j = 0; j <= size - 1; j++)
This is the sample code which is generating the desired result:
int[] array = { 1, 2, 3, 4 };
int size = 2;
for (int j = 0; j < array.length; j++) {
for (int i = 0; i <= array.length - size; i++) {
int[] temp = Arrays.copyOfRange(array, i, i + size);
for (int x : temp) {
System.out.print(x + ",");
}
System.out.println();
}
size++;
if (size == array.length) {
break;
}
}
Output:
1,2,
2,3,
3,4,
1,2,3,
2,3,4,

Categories