Suppose I have 2D array as follow:
int[][] temp={
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}};
and i want to get sub-array start from X direction 1 to 2 and Y direction 1 to 2 i.e.
{6,7}
{10,11}
can anyone give me solution for above problem.
Here you are
int[][] temp = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
int[][] a = new int[temp.length][];
for (int i = 0; i < temp.length; i++) {
a[i] = Arrays.copyOfRange(temp[i], 1, 3);
}
System.out.println(Arrays.deepToString(a));
output
[[2, 3], [6, 7], [10, 11]]
answering your question in comment if we want to access only [[6, 7], [10, 11]]
int[][] a = new int[2][];
for (int i = 1, j = 0; i < 3; i++, j++) {
a[j] = Arrays.copyOfRange(temp[i], 1, 3);
}
output
[[6, 7], [10, 11]]
As an example without using the Arrays class:
int[][] temp = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } };
int[][] subArray = new int[temp.length][];
for (int i = 0; i < subArray.length; i++) {
subArray[i] = new int[2];
subArray[i][0] = temp[i][1];
subArray[i][1] = temp[i][2];
}
You can then access any part of subArray that you want. This will access the values [[6, 7], [10, 11]]:
for (int x = 1; x < 3; x++) {
System.out.println(subArray[x][0]);
System.out.println(subArray[x][1]);
}
[Additional] To address the modified question:
If you want to create a smaller array you can play around with the start and end points of the loop, and the indices accessed within the loop, for example this will create the array you ask for:
int[][] subArray = new int[2][];
for (int i = 1; i < temp.length; i++) {
subArray[i-1] = new int[2];
subArray[i-1][0] = temp[i][1];
subArray[i-1][1] = temp[i][2];
}
You could instantiate a new array and loop through the appropriate indices of the original array to initialize the subarray.
Related
I have an array like this one-
{1, 2, 3, 4, 5, 6}
I want to sort it in the order of multiples of 3 with remainders 0, 1 and 2. (the first group is multiples of 3, the second one is multiples of 3 with remainder 1 and the last one is multiples of 3 with remainder 2) and I want to preserve the order in which elements appear in the array.
The result should be -
{3, 6, 1, 4, 2, 5}
I have this code-
int current = 0;
int b = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = current; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
b = numbers[j];
numbers[j] = numbers[current];
numbers[current] = b;
current++;
}
}
}
But this code does not preserve the order in which elements appear in the array. The result I got is-
{3, 6, 1, 4, 5, 2}
But I want the result to be like {3, 6, 1, 4, 2, 5}. How can I achieve this?
Using stream and comparator
int[] array = {1, 2, 3, 4, 5, 6};
List<Integer> lst = Arrays.stream(array)
.boxed()
.sorted(Comparator.comparingInt(o -> o % 3))
.collect(Collectors.toList());
System.out.println(lst);
In your solution you are swapping the elements in place, which shuffles them from the initial order. That's why you don't have the same ordering at the end. I'm not sure if there is another way apart from having a second array to keep the sorted elements, while at the same time iterating over the original one like so:
public static void main(String[] args) {
int[] numbers = new int[]{1, 2, 3, 4, 5, 6};
int[] result = new int[numbers.length];
int b = 0;
int current = 0;
for (int i = 0; i < 3; i++) { //3 groups
for (int j = 0; j < numbers.length; j++) {
if (numbers[j] % 3 == i) { //reminder should be 0,1 or 2
result[current] = numbers[j];
current++;
}
}
}
System.out.println(Arrays.toString(result));
}
Output: [3, 6, 1, 4, 2, 5]
You can use an IntStream and a Comparator to sort the stream:
int[] arr = {1, 2, 3, 4, 5, 6};
int[] arrSorted = IntStream.of(arr).boxed()
.sorted(Comparator.comparingInt(i -> i % 3))
.mapToInt(Integer::intValue)
.toArray();
System.out.println(Arrays.toString(arrSorted));
Output:
[3, 6, 1, 4, 2, 5]
Note: From IntStream.of() javadoc:
Returns a sequential ordered stream whose elements are the specified
values.
I would create a new array of the same size and then place the elements in the correct order. For example like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = new int[array.length];
int counter = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < array.length; j++) {
if (array[j] % 3 == i) {
sorted[counter] = array[j];
counter++;
}
}
}
System.out.println(Arrays.toString(sorted));
Output:
[3, 6, 1, 4, 2, 5]
Alternatively, you can use Java 8 features to reduce the amount of code like this:
int[] array = {1, 2, 3, 4, 5, 6};
int[] sorted = Arrays.stream(array).boxed().sorted(Comparator.comparingInt(a -> (a % 3))).mapToInt(i -> i).toArray();
Output:
[3, 6, 1, 4, 2, 5]
Im not exactly sure how to word this, I am trying to access different variables within a loop. Here is an example:
int[] box0 = {1,2,3};
int[] box1 = {4,5,6};
for(int i = 0; i < 2; i++){
box'i'[i] = 0; //Where I first change the elements of the box0 array then of box1 array.
}
I do not know how to concatenate, access, or otherwise use the other array. I am pretty new to java so please keep solutions as simple as possible. Thanks.
It would make sense to use array of arrays and then address an element of such array:
int[] box0 = {1, 2, 3};
int[] box1 = {4, 5, 6};
int[][] box = {box0, box1};
for (int i = 0; i < 2; i++) {
box[i][i] = 0; // however, here an elements are changed at diagonal cells
}
If all elements need to be changed by "row", a nested loop should be used:
int[] box0 = {1, 2, 3};
int[] box1 = {4, 5, 6};
int[][] box = {box0, box1};
for (int i = 0; i < box.length; i++) {
for (int j = 0; j < box[i].length; j++) {
box[i][j] = 0;
}
}
It really depends on what you're trying to do. I cannot really determine what you are trying to achieve so I'm giving multiple possible options:
Iterate through an array
int[] box0 = {1,2,3};
int[] box1 = {4,5,6};
for(int i = 0; i < 3; i++)
{
box0[i] = 0;
}
This code will iterate over the elements 0 to 3 of the box0 array and set the value to 0.
Result:
box0 = [0, 0, 0]
box1 = [4, 5, 6]
Iterate over multiple arrays
int[] box0 = {1,2,3};
int[] box1 = {4,5,6};
int[][] allArrays = {box0, box1};
for(int i = 0; i < 2; i++)
{
allArrays[i][0] = 5;
}
This code will iterate over the elements 0 to 2 of the allArrays array (which contains both arrays box0 and box1) and set the value of their first element to 5.
Result:
box0 = [5, 2, 3]
box1 = [5, 5, 6]
allArrays = [[5, 2, 3], [5, 5, 6]]
I am doing a project where I have to make a matrices from a 2D array. One of the requirements is to covert a 3x4 2D array (with values stored in) to a 6x2 2d array (with the same values)?
public int[][] covertMatrix(int[][] ma, int r, int c) {
rw = r;
col = c;
this.ma = new int[rw][col];
for (int i = 0; i < rw; i++) {
for (int j = 0; j < col; j++) {
ma[i][j] = ma[i][j];
}
}
return ma;
}
I've tried this code and it reshapes the array but only prints a 2D array of zeroes.
This version redistributes the values to the new array.
Calculating the indexes by dividing the cellindex by the colums which gives the row and calculating the rest wich gives to new column.
public int[][] covertMatrix(int[][] ma, int r, int c) {
rw = r;
col = c;
int element = 0;
int[][] ma2 = new int[rw][col];
for (int i = 0; i < ma.length; i++) {
for (int j = 0; j < ma[i].length; j++) {
final int newRow = (element)/col; //integer division ignoring rest.
final int newCol = (element)%col; // rest of the division.
ma2[newRow][newCol] = ma[i][j];
element++;
}
}
this.ma = ma2;
return ma2;
}
System.err.println(Arrays.deepToString(covertMatrix(new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12}},6,2)));
-> [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
You can change your method to :
public int[][] covertMatrix(int[][] ma, int r, int c) {
int trans[][] = new int[r][c];
int count = 0; // used to increment the list elements
// fetch all elements from the original array 'ma'
List<Integer> collectList = Arrays.stream(ma).flatMapToInt(Arrays::stream)
.boxed().collect(Collectors.toList());
// assign the values from the list to resp array indices
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
trans[i][j] = collectList.get(count);
count++;
}
}
return trans;
}
Logic :
Create a 2D array of your required dimensions, here trans with r and c.
Now collect all the elements of the array ma to a list collectList
Iterate over the newly created array, fetch the values from the list and assign them to the respective indices.
What you have is a starting matrix of 3x4 like
+--+--+--+--+
|01|02|03|04|
+--+--+--+--+
|05|06|07|08|
+--+--+--+--+
|09|10|11|12|
+--+--+--+--+
that you want to convert in a 6x2 matrix like
+--+--+
|01|02|
+--+--+
|03|04|
+--+--+
|05|06|
+--+--+
|07|08|
+--+--+
|09|10|
+--+--+
|11|12|
+--+--+
To do that, clearly tab1[i][j] = tab2[i][j] will not work. You need to translate address between the two arrays. At first sight, using the modulo for the row and the rest of the division for the col would do the trick.
Something like
public static void main(String[] args) {
int[][] tab1 = new int[][]{{1,2,3,4},{5,6,7,8},{9,10,11,12}};
System.out.println(Arrays.deepToString(tab1));
System.out.println("---------------------------");
int size = tab1.length * tab1[0].length;
for(int i = 1; i <= size; i++){
int j = size % i;
if(j == 0){
convert(tab1, i, size/i);
}
}
}
private static void convert(int[][] tab1, int row, int col) {
System.out.println(String.format("converting to %dx%d", row, col));
int[][] tab2 = new int[row][col];
for(int i = 0; i < row; i++){
for(int j = 0; j < col; j++){
int index = i*col + j;
int newRow = index / tab1[0].length;
int newCol = index % tab1[0].length;
tab2[i][j] = tab1[newRow][newCol];
}
}
System.out.println(Arrays.deepToString(tab2));
System.out.println("---------------------------");
}
Which give the output
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
---------------------------
converting to 1x12
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]
---------------------------
converting to 2x6
[[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]
---------------------------
converting to 3x4
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
---------------------------
converting to 4x3
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
---------------------------
converting to 6x2
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
---------------------------
converting to 12x1
[[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]]
---------------------------
I'm looking for a hint on how to solve this or where I am going wrong.
The question is as follows: Write a static method named stretch that accepts an array of integers as a parameter and returns a new array twice as large as the original, replacing every integer from the original array with a pair of integers, each half the original. If a number in the original array is odd, then the first number in the new pair should be one higher than the second so that the sum equals the original number. For example, if a variable named list refers to an array storing the values {18, 7, 4, 24, 11}, the call of stretch(list) should return a new array containing {9, 9, 4, 3, 2, 2, 12, 12, 6, 5}. (The number 18 is stretched into the pair 9, 9, the number 7 is stretched into 4, 3, the number 4 is stretched into 2, 2, the number 24 is stretched into 12, 12 and the number 11 is stretched into 6, 5.)
Test your code with the following class:
import java.util.*;
public class TestStretch {
public static void main(String[] args) {
int[] list = {18, 7, 4, 14, 11};
int[] list2 = stretch(list);
System.out.println(Arrays.toString(list)); // [18, 7, 4, 24, 11]
System.out.println(Arrays.toString(list2)); // [9, 9, 4, 3, 2, 2, 7, 7, 6, 5]
}
// your code goes here
}
This is currently what I have, but it is not quite working correctly... I have a feeling it is how i'm using int i and int j, but i'm not sure what to do to fix it so that it works as intended.
import java.util.*;
public class TestStretch {
public static void main(String[] args) {
int[] list = {18, 7, 4, 14, 11};
int[] list2 = stretch(list);
System.out.println(Arrays.toString(list)); // [18, 7, 4, 24, 11]
System.out.println(Arrays.toString(list2)); // [9, 9, 4, 3, 2, 2, 7, 7, 6, 5]
}
public static int[] stretch(int[] array){
int length = array.length;
int[] newArray = new int[array.length*2];
for(int i = 0; i< length; i=i+2){
int j = 0;
if(array[i] % 2 == 0){
newArray[i] = (array[j]/2);
newArray[i+1] = newArray[i];
j++;
} else{
newArray[i] = (array[j]/2);
newArray[i+1] = (newArray[i] + 1);
j++;
}
}
return newArray;
}
}
The output I get is:
[18, 7, 4, 14, 11]
[9, 9, 9, 9, 9, 10, 0, 0, 0, 0]
Instead of:
[18, 7, 4, 24, 11]
[9, 9, 4, 3, 2, 2, 7, 7, 6, 5]
There are a couple of mistakes:
The loop iterates only until half of the array, skipping elements by 2
The value of j is reset to 0 in each iteration
Also, the algorithm can be simplified:
For each index i in the input, you want to set in the destination at position 2 * i and 2 * i + 1.
The second value to set is simply the original value divided by 2, with integer truncation
The first value to set is the same as the second, +1 if the division by 2 leaves a remainder
With the above issues corrected, and the implementation simplified:
int[] newArray = new int[array.length * 2];
for (int i = 0; i < array.length; i++) {
newArray[2 * i] = array[i] / 2 + array[i] % 2;
newArray[2 * i + 1] = array[i] / 2;
}
return newArray;
First of all, if you are looping to the old array's length, don't increment i by 2.
If i increases by 1 each time, we need to figure out how to map the old array's index i to the new array's index. It is quite simple: the new array's indices are just i*2 and i*2+1.
Now j seems redundant because it always holds the same value as i, so you can remove that.
This is the full code:
int length = array.length;
int[] newArray = new int[array.length*2];
for(int i = 0; i< length; i++){
if(array[i] % 2 == 0){
newArray[i*2] = (array[i]/2);
newArray[i*2+1] = newArray[i*2];
} else{
newArray[i*2] = (array[i]/2);
newArray[i*2+1] = (newArray[i*2] + 1);
}
}
return newArray;
Three mistakes:
j should be initialized outside the for-loop
we should use j to record the new value into the new array
we should increment j upon every iteration in 2 - and we should increment i only by 1 (since we're using j to insert two item while we use i to iterate the original array):
int j = 0;
for(int i = 0; i< length; i++){
if(array[i] % 2 == 0){
newArray[j] = newArray[j+1] = array[i]/2;
} else{
newArray[j] = array[i]/2 + 1;
newArray[j+1] = array[i]/2;
}
j += 2;
}
Note: giving a variable that holds an array the name "list" might create confusion!
for(int i = 0; i< length; i=i+2){
length is the length of the original array, so you iterate only over half of the values because you increase i by 2 each step.
if(array[i] % 2 == 0){
This should be
if(array[j] % 2 == 0){
And because you define j within your for-loop, array[j] always returns 18. Oh and you set the second element of the tuple to be the higher one while your comment in the code says the contrary should take place.
So a fixed version of your method would look like this:
public static int[] stretch(int[] array){
int length = array.length;
int[] newArray = new int[array.length*2];
int j = 0;
for(int i = 0; i< newArray.length; i=i+2){
if(array[j] % 2 == 0){
newArray[i] = (array[j]/2);
newArray[i+1] = newArray[i];
} else{
newArray[i+1] = (array[j]/2);
newArray[i] = (newArray[i+1] + 1);
}
j++;
}
return newArray;
}
Avoiding duplicate code:
public static int[] stretch(int[] array){
int[] newArray = new int[array.length*2];
int j = 0;
for(int i = 0; i< newArray.length; i=i+2){
int val = array[j];
newArray[i] = (val/2);
newArray[i+1] = newArray[i];
if(val % 2 != 0){
newArray[i]++;
}
j++;
}
return newArray;
}
Or using fancy streams:
public static int[] stretch(int[] array){
return Arrays.stream(array)
.flatMap(elem -> {
int half = elem / 2;
int otherHalf = half;
if (elem % 2 != 0) {
half++;
}
return IntStream.of(half, otherHalf);
}).toArray();
}
}
What is the best way to concatenate two arrays with alternating values?
Let's say array1 is:
[1, 3, 5, 7]
array2 is:
[2, 4, 6, 8]
I want to combine these two arrays, so that the result is:
[1, 2, 3, 4, 5, 6, 7, 8]
In Java:
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length * 2];
for (int i = 0; i < concat.length; i++) {
// concatenation
}
System.out.println(concat.toString());
// should be [1, 2, 3, 4, 5, 6, 7, 8]
Update: No sorting is required, as the arrays are already sorted, using Arrays.sort(array)
A basic way
int[] concat = new int[a1.length * 2];
int index = 0;
for (int i = 0; i < a1.length; i++) {
concat[index++] = a1[i];
concat[index++] = a2[i];
}
assuming that both array will be of same size.
Put the elements of both array in a list and then sort it.You can use lambdas also
Integer[] a1 = { 1, 3, 5, 7 };
Integer[] a2 = { 2, 4, 6, 8 };
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(a1));
list.addAll(Arrays.asList(a2));
System.out.println("Before Sorting "+list);
Collections.sort(list,(a, b) -> Integer.compare(a,b));
System.out.println("After Sorting "+list);
Output
Before Sorting [1, 3, 5, 7, 2, 4, 6, 8]
After Sorting [1, 2, 3, 4, 5, 6, 7, 8]
If you want to zip together any length arrays (where then lengths differ, the remaining is appended to the result):
public static int[] zip(int[] a, int[] b){
int[] result = new int[a.length + b.length];
int index = 0;
final int minLen = Math.min(a.length, b.length);
for (int i = 0; i < minLen; i++) {
result[index++] = a[i];
result[index++] = b[i];
}
if(a.length > minLen)
System.arraycopy(a, minLen, result, index, a.length - minLen);
else if(b.length > minLen)
System.arraycopy(b, minLen, result, index, b.length - minLen);
return result;
}
Try it like this:
int[] concat = new int[a1.length + a2.length];
int k = 0, m = 0;
for (int i = 0; i < concat.length; i++) {
if( k < al.length && a1[k] <= a2[m])
concat[i] = a1[k++];
else
concat[i] = a2[m++];
}
NB: The result will be sorted as in your desired output.
you could also use two variables in your loop like this
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length + a2.length];
for (int i = 0, j = 0; i+j < concat.length;) {
if(i<a1.length) {
concat[i+j] = a1[i++];
}
if(j<a2.length) {
concat[i+j] = a2[j++];
}
}
System.out.println(Arrays.toString(concat));
Try This if it solves ur problem
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8 };
int[] concat = new int[a1.length + a2.length];
System.arraycopy(a1, 0, concat, 0, a1.length);
System.arraycopy(a2, 0, concat, a1.length, a2.length);
Arrays.sort(concat);
System.out.println(Arrays.toString(concat));
Output:
[1, 2, 3, 4, 5, 6, 7, 8]
There are utility methods for example addALL() method from ArrayUtil class. But what they do is simple concatenate. For your problem you need to write your own logic. For example the following code ensures correct alternate concatenation even if arrays are of unequal length.
int[] a1 = { 1, 3, 5, 7 };
int[] a2 = { 2, 4, 6, 8, 9, 10, 122 };
int totalLen = a1.length + a2.length;
int[] concat = new int[totalLen];// I made a change here incase the
// arrays are not of equal length
int i = 0; // this will be the concat array index counter
int j1 = 0; // this will be the a1 array index counter
int j2 = 0; // this will be the a2 array index counter
while (i < totalLen) {
if ((j1 < a1.length)) {
concat[i] = a1[j1];
i++;
j1++;
}
if ((j2 < a2.length)) {
concat[i] = a2[j2];
i++;
j2++;
}
}