I have a 2d array, let's say like this :
2 0 8 9
3 0 -1 20
13 12 17 18
1 2 3 4
2 0 7 9
How to create an array reduced by let's say 2nd row and third column?
2 0 9
13 12 18
1 2 4
2 0 9
Removing rows and columns in arrays are expensive operations because you need to shift things, but these methods do what you want:
static int[][] removeRow(int[][] data, int r) {
int[][] ret = new int[data.length - 1][];
System.arraycopy(data, 0, ret, 0, r);
System.arraycopy(data, r+1, ret, r, data.length - r - 1);
return ret;
}
static int[][] removeColumn(int[][] data, int c) {
for (int r = 0; r < data.length; r++) {
int[] row = new int[data[r].length - 1];
System.arraycopy(data[r], 0, row, 0, c);
System.arraycopy(data[r], c+1, row, c, data[r].length - c - 1);
data[r] = row;
}
return data;
}
You may want to investigate other data structures that allow for cheaper removals, though, i.e. doubly-linked lists. See, for example, Dancing Links.
public class TestMe {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int array[][] = {{2,0, 8, 9,},
{3, 0, -1, 20},
{13, 12, 17, 18},
{1, 2, 3, 4,},
{2, 0, 7, 9}};
for(int i=0; i<array.length;i++){
if(i == 1 ){
continue;
}
for(int j=0; j<array[i].length;j++){
if(j==2){
continue;
}
System.out.print(array[i][j]+" ");
}
System.out.println("");
}
}
}
Related
I know how to generally manipulate and create a multidimensional array but I don't know all the utils and features that arrays have. I want to know is if I have a 2D array the size of [5][4], can I print it where the first line is in order, second is in reverse, and the third is in order... and so on.
For example:
[1 2 3 4] //in order
[8 7 6 5] //reverse
[9 10 11 12] //in order
[16 15 14 13] //reverse
[17 18 19 20] //in order
as my teacher stated "Define a two-dimensional array of size m × n. Write a method to initialize this array with numbers from 1 to m × n in the way as below: the first row, initialize the elements from left to right; the second row, initialize from right to left; then switch order. For example, if m=5; and n = 4; the array should be initialized to:"
I’m not sure if it should be done using a temp method or some other loop method.
You cannot reverse it directly. But you can have a loop and reverse the alternative rows:
void reverseArray() {
Integer[][] arr = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16},
{17, 18, 19, 20}};
for (int i = 1; i < arr.length; i += 2) {
Collections.reverse(Arrays.asList(arr[i]));
}
}
if I have a 2D array the size of [5][4], can I print it where the
first line is in order, second is in reverse, and the third is in
order... and so on.
It's unclear how you want to use the output, but here is a literal way to do it:
public static void main(String[] args) {
int[][] values = new int[][]{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
};
for (int r = 0; r < values.length; r++) {
if (r % 2 == 0) {
// forwards
for (int c = 0; c < (values[r].length - 1); c++) {
System.out.print(values[r][c] + " ");
}
System.out.println(values[r][values[r].length - 1]);
} else {
// backwards
for (int c = (values[r].length - 1); c > 0; c--) {
System.out.print(values[r][c] + " ");
}
System.out.println(values[r][0]);
}
}
}
Output:
1 2 3 4
8 7 6 5
9 10 11 12
16 15 14 13
int[][] arr = new int[][]{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}};
AtomicInteger counter = new AtomicInteger(0);
Arrays.stream(arr).forEach(ints -> {
System.out.println(Arrays.stream(ints)
.mapToObj(String::valueOf)
.reduce((a, b) ->
counter.get() % 2 == 0 ? a + " " + b : b + " " + a).get());
counter.incrementAndGet();
});
This code uses the Stream API to iterate over an array. The first stream iterates over single-level arrays, the second - their elements, and then forms a string. Also, according to the counter value, items are combined from left to right or from right to left.
You can create such an array with a "snake order" without sorting at all, using a stream in a stream or a loop in a loop:
int m = 5;
int n = 4;
int[][] arr = IntStream
// create rows of array
.range(0, m).mapToObj(row -> IntStream
// for each row create cells where
// values are numbers from 1 to [m * n]
.range(0, n).map(cell -> {
int val = row * n;
if (row % 2 == 0)
// even rows:
// straight order
val += cell + 1;
else
// odd rows:
// reverse order
val += n - cell;
return val;
})
// return int[] array
.toArray())
// return int[][] 2d array
.toArray(int[][]::new);
int m = 5;
int n = 4;
int[][] arr = new int[m][n];
// create rows of array
for (int row = 0; row < m; row++) {
// for each row create cells where
// values are numbers from 1 to [m * n]
for (int cell = 0; cell < n; cell++) {
int val = row * n;
if (row % 2 == 0)
// even rows:
// straight order
val += cell + 1;
else
// odd rows:
// reverse order
val += n - cell;
arr[row][cell] = val;
}
}
Arrays.stream(arr).map(Arrays::toString).forEach(System.out::println);
// [1, 2, 3, 4]
// [8, 7, 6, 5]
// [9, 10, 11, 12]
// [16, 15, 14, 13]
// [17, 18, 19, 20]
See also:
• How do I rotate a matrix 90 degrees counterclockwise in java?
• Is there any other way to remove all whitespaces in a string?
Not as efficient as nested loops, one can simply iterator from 1 to 20 and determine row i and column j.
final int M = 5;
final int N = 4;
int[][] matrix = new int[M][N];
IntStream.range(0, M*N)
.forEach(no -> { // no = 0, 1, 2, ... , M*N-1
int i = no / N; // Row.
int j = no % N; // Increasing column (for even row).
if (i % 2 == 1) { // Odd row.
j = N - 1 - j; // Decreasing column.
}
matrix[i][j] = no + 1;
});
i % 2 is the modulo 2, rest by division of 2, hence 0 for even, 1 for odd.
Or use a bit more language features:
IntStream.range(0, N)
.forEach(i -> {
int no = N * i;
IntUnaryOperator jToValue = i % 2 == 0
? j -> no + 1 + j
: j -> no + N - 1 -j;
Arrays.setAll(matrix[i], jToValue);
});
Here Arrays.setAll(int[], (int index) -> int) fills the array based on the index.
About the question of there being some nice function:
You probably saw List.reverse; there does not exist an Arrays.reverse, hence Arrays.setAll seems to be best. In this case where the values are increasing one theoretically could also sort all odd rows reversed. But only with a trick, and sorting costs.
It is interesting that there are so many solutions. Instead of waggling the dog's tail one can take the tail and waggle the dog.
I have 3 arrays of random length. I want to create a new array that stores the largest value from comparing those 3 arrays at each index.
int size1=x.length;
int size2=y.length;
int size3=z.length;
int size=0;
if (size1>=size2 && size1>=size3)
size=size1;
else if (size2>=size1 &&size2>=size3) {
size=size2;
}
else if (size3>=size1 && size3>=size2) {
size=size3;
}
int[] largest= new int[size];
int[] x= {1, 4, 6}; // random array length from 1-5 and hypothetically each array hold these values
int[] y= {2, 4};
int[] z= {5, 6, 7, 8, 9};
// ideally after some sort of an algorithm largest[] should hold {5, 6, 7, 8, 9}
I initially thought of a for loop, but my loop will eventually throw me a out of bound exception, because of the random size length nature of the arrays and x/y/z won't hold a value at index [i]. Any other ways?
for (int i=0;i<size;i++) {
if (x[i]>y[i]) && t1[i]>t3[i]) {
largest[i]=x[i];
}
else if (y[i]>x[i]) && y[i]>z[i]) {
largest[i]=y[i];
}
else if (z[i]>x[i]) && z[i]>y[i]) {
largest[i]=z[i];
}
}
There are several ways of doing this. Here's one that avoids a ton of conditional statements at the cost of more memory.
int size = Math.max(x.length, Math.max(y.length, z.length));
int[] nooX = new int[size];
int[] nooY = new int[size];
int[] nooZ = new int[size];
// Copy over the values from x to the new array
for(int i = 0; i < x.length; i++){
nooX[i] = x[i];
}
// ... Copy paste the above and do the same for arrays nooY and nooZ
int[] largest = new int[size];
// ... Copy paste your code, using nooX, nooY, and nooZ instead of x, y, and z
A simpler approach without creating extra arrays to equalize size:
public static int[] getMaxValues(int[] x, int[] y, int[] z) {
int size = Math.max(x.length, Math.max(y.length, z.length));
int[] max = new int[size];
for (int i = 0; i < size; i++) {
int xi = i < x.length ? x[i] : Integer.MIN_VALUE;
int yi = i < y.length ? y[i] : Integer.MIN_VALUE;
int zi = i < z.length ? z[i] : Integer.MIN_VALUE;
max[i] = Math.max(xi, Math.max(yi, zi));
}
return max;
}
Test:
int[] x= {4, 4, 6}; // random array length from 1-5 and hypothetically each array hold these values
int[] y= {2, 10};
int[] z= {3, 6, 7, 8, 9};
System.out.println(Arrays.toString(getMaxValues(x, y, z)));
Output:
[4, 10, 7, 8, 9]
Update
Defining a couple of functions allows to create the following implementation using Stream API that would be able to handle non-hardcoded number of arrays:
private static int getAtIndex(int[] arr, int i) {
return i < arr.length ? arr[i] : Integer.MIN_VALUE;
}
private static int getMax(IntStream values) {
return values.max().getAsInt();
}
// use Supplier to be able to use stream of the arrays twice
public static int[] getMaxValues(Supplier<Stream<int[]>> arrs) {
return IntStream.range(0, getMax(arrs.get().mapToInt(arr -> arr.length)))
.map(i -> getMax(arrs.get().mapToInt(arr -> getAtIndex(arr, i))))
.toArray();
}
Test:
int[] maxValues = getMaxValues(() -> Stream.of(x, y, z)); // supply stream of arrays
System.out.println(Arrays.toString(maxValues));
I think we should think this way
array1 = 1, 2, 3, 4, 6, 7
array2 = 3, 4, 5, 6, 23, 4
array3 = 5, 5, 32, 3, 2, 43, 56
Like a matrix
1 2 3 4 6 7
3 4 5 6 23 4
5 5 32 3 2 43 56
We need is the greatest value in every column.
largestArr = 5, 5, 32, 6, 23, 43, 56 <-- Like this
I hope this code is the answer to your problem.
public static int[] largestColumnsArr(int arr1[], int arr2[], int arr3[]) {
int[][] arr = {arr1, arr2, arr3};
//The size of the largest sized array
int size = Math.max(arr3.length, Math.max(arr2.length, arr1.length));
int[] largestArr = new int[size];
/*
Takes the largest value in each column and assigns it to the array
If it is try catch, if the size of the arrays is exceeded, the program exit is blocked.
*/
for (int i = 0; i < size; i++) {
int largestColumnValue = 0;
try {
for (int j = 0; j < arr.length; j++) {
if (largestColumnValue < arr[j][i]) {
largestColumnValue = arr[j][i];
}
}
} catch (Exception e) {
}
largestArr[i] = largestColumnValue;
}
return largestArr;
}
hello to all you code geniuses on here
ill try to explain my problem as simply as i can
image1
To produce image1, lets say an array like below is required, keeping in mind that the numbers are placed left to right in the first row, then go backwards in the second row, and if you added more numbers, it would create a third row.
int[] something = {1, 2, 3, 2, 1, 2, 1, 3, 3, 1, 1, 2}
so i want to make to make a "map" of the layout, like this desired output below.
2 1 1 3 3 1
1 2 3 2 1 2
and then from there i would want to find the total for each column, so like this.
2 1 1 3 3 1
1 2 3 2 1 2
..................
3 3 4 5 4 3
(and i then want to make store this layout and sum within another array)
hopefully that all made sense, if so,
how could i go about doing this?
thanks heaps : )
Seems like you can use a two-dimensional array data structure to solve this:
int[][] something = new int[][]{
{2, 1, 1, 3, 3, 1},
{1, 2, 3, 2, 1, 2}
};
int totalForColomn1 = something[0][0] + something [1][0];
int totalForColomn2 = something[0][1] + something [1][1];
// ...
int totoalForColomn6 = something[0][5] + something [1][5];
If you could only use one-dimensional array:
int[] something = new int[] {2, 1, 1, 3, 3, 1, 4, 2, 3, 2, 1, 2};
int row_size = 6;
int totalForColomn1 = something[0] + something[0 + row_size];
int totalForColomn2 = something[1] + something[1 + row_size];
// ...
int totalForColomn6 = something[5] + something[5 + row_size];
Remember to keep a consistant row_size by putting those undecided element to 0.
In this case, you should init your array like:
int[] something = new int[] {0, 0, 0, 0, 1, 4, 1, 2, 3, 2, 1, 1};
So If I am reading this correctly if L is the length of your array you want to add the nth and L-1-nth element of the array and store the result in an array. I through this together quickly so I did not handle what happens if the input array is of odd length (your question did not specify).
import java.util.Arrays;
public class App {
public static void main(String[] args) {
int[] something = {1, 2, 3, 2, 1, 2, 1, 3, 3, 1, 1, 2};
System.out.println(Arrays.toString(addValues(something)));
}
public static int [] addValues(int [] input){
int[] output = new int[input.length / 2];
for(int i = 0; i<input.length/2; i++){
output[i] = input[i] + input[input.length -1 - i ];
}
return output;
}
}
EDIT:
I think this will work for the case where the are an arbitrary number of rows.
The main insite into how this work is in the grid below.
0 1 2 3 4 5 :row 0
11 10 9 8 7 6 :row 1
12 13 14 15 16 17:row 2
23 22 21 20 19 18:row 3
So whether the output index is going up or down is determined by the row number and every time we hit an input index that is the same size as our output array we need to stay at the same output index.
import java.util.Arrays;
public class App {
public static void main(String[] args) {
int[] something = { 1, 2, 3, 2, 1, 2, 1, 3, 3, 1, 1, 2 };
System.out.println(Arrays.toString(addValues(something, 6)));
}
public static int[] addValues(int[] input, int row_lenth) {
int[] output = new int[row_lenth];
int output_index = 0;
for (int i = 0; i < input.length; i++) {
if (i % row_lenth != 0) {
if ((i / row_lenth) % 2 == 0) {
output_index++;
} else {
output_index--;
}
}
output[output_index] += input[i];
}
return output;
}
}
import java.util.Scanner;
public class Stckoverq {
public static void main(String args[]) {
Scanner sn = new Scanner(System.in);
System.out.print("What is the size of array? ");
int size = sn.nextInt();
System.out.print("What is length of the row?");
int len = sn.nextInt();
int ind = 0, i = 0, j = 0;
//variable 'ind' is for getting the element from arr[] array at index ind
int rac[][] = new int[size/len][len];
//variable 'i' and 'j' is for storing rows and column elements respectively in array rac[]
int arr[] = new int[size];
System.out.println("Enter array elements: ");
for(int k=0;k<size;k++)
arr[k] = sn.nextInt();
while(ind!=arr.length)
{
if(j==len) {
j=0; //Reset column index
i++; //Increase row index
}
rac[i][j] = arr[ind];
ind++;
j++; //Increase column index
}
//Now print the rows and columns................
for(int r =0;r<size/len;r++) {
for(int c=0;c<len;c++)
System.out.print(rac[r][c]+"\t");
System.out.println();
}
int sum[] = new int[len];
//this array sum[] is used to store sum of all row elements.
int s = 0;
for(int c=0;c<len;c++) {
for(int r =0;r<size/len;r++)
s += rac[r][c];
sum[c] = s;
s = 0;
}
for(int x: sum)
System.out.print(x+"\t");
}
}
I am trying to represent an array in form of a Minimum-Heap. And I am facing a problem in one of the leaf nodes, where parent is greater than (12 grater than 6) the right child. I am not understanding what is wrong in my coding, please help.
Here is my code:
public class MinHeap {
public void heapify(int Array[], int i){
int min;
int left=2*i;
int right= 2*i+1;
int length=Array.length;
if(left<length && Array[left]< Array[i] && Array[left]< Array[right])
min=left;
else if(right<length && Array[right]<Array[i] && Array[right]<Array[left])
min=right;
else min=i;
if(min!=i){
int temp=Array[i];
Array[i] = Array[min];
Array[min]=temp;
heapify(Array,min);
}
}
public void display(int Array[]){
for(int i=0; i<Array.length; i++)
System.out.print(Array[i]+" ");
}
public static void main(String[] args){
int Array[]={2,1,4,5,6,100,0,9,8,3,12,32,6,7,1000,999,20};
//int Array[]={1, 8, 9, 2, 10, 14, 3, 4, 7, 16};
int length=Array.length;
MinHeap object= new MinHeap();
System.out.println(length);
object.display(Array);
System.out.println();
for(int i=(length/2)-1;i>=0;i--){
object.heapify(Array,i);
}
System.out.println();
object.display(Array);
}
}
The output that I am getting is:
0 1 3 2 4 12 5 9 8 6 100 32 6 7 1000 999 20
Try this.
static void heap(int[] a) {
for (int i = 0; i < a.length; ++i) {
while (true) {
int p = (i - 1) / 2;
if (a[p] <= a[i])
break;
int t = a[i];
a[i] = a[p];
a[p] = t;
i = p;
}
}
}
and
int a[]={2,1,4,5,6,100,0,9,8,3,12,32,6,7,1000,999,20};
heap(a);
System.out.println(Arrays.toString(a));
// -> [0, 2, 1, 5, 3, 6, 4, 9, 8, 6, 12, 100, 32, 7, 1000, 999, 20]
Your children index is calculated wrong. You should use:
int left=2*i+1;
int right=2*i+2;
And the output will be:
0 1 2 5 3 6 4 9 8 6 12 32 100 7 1000 999 20
Say I have the following 2d array in Java set to a variable named myMap:
1 3 1
3 2 3
1 3 1
The next step in my program is to add rows and columns of zeros as follows:
1 0 3 0 1
0 0 0 0 0
3 0 2 0 3
0 0 0 0 0
1 0 3 0 1
Basically, I'm adding arrays of zero into the spaces between the previous rows/columns. I then fill them in with appropriate numbers (irrelevant to my question) and repeat the process (adding more rows/columns of zeros) a finite number of times.
My question is as follows- what is the easiest and most efficient way to do this in Java? I know I could create a new 2d array and copy everything over, but I feel like there may be a more efficient way to do this. My intuition says that a 2d ArrayList may be the better way to go.
Also, and this my be important, when my program begins, I DO know what the maximum size this 2d array. Also, I cannot expect the symmetry of the numbers that I put in for this example (these were just put in for a good visual reference).
Here's a solution with ArrayLists: (test included)
int[][] ar = new int[][]
{
{ 0, 1, 2 },
{ 3, 4, 5 },
{ 6, 7, 8 } };
ArrayList<ArrayList<Integer>> a = new ArrayList<>(ar.length);
ArrayList<Integer> blankLine = new ArrayList<>(ar.length * 2 - 1);
for (int i = 0; i < ar.length * 2 - 1; i++)
{
blankLine.add(0);
}
for (int i = 0; i < ar.length; i++)
{
ArrayList<Integer> line = new ArrayList<>();
for (int j = 0; j < ar[i].length; j++)
{
line.add(ar[i][j]);
if (j != ar[i].length - 1)
line.add(0);
}
a.add(line);
if (i != ar.length - 1)
a.add(blankLine);
}
for (ArrayList<Integer> b : a)
{
System.out.println(b);
}
Output:
[0, 0, 1, 0, 2]
[0, 0, 0, 0, 0]
[3, 0, 4, 0, 5]
[0, 0, 0, 0, 0]
[6, 0, 7, 0, 8]
Algorithm
int[][] appendRows(int[][] bag, int[]... rows) {
int[][] extendedBag = new int[bag.length + rows.length][];
int i = 0;
for (int[] row : bag) { fillRow(extendedBag, row, i++); }
for (int[] row : rows) { fillRow(extendedBag, row, i++); }
return extendedBag;
}
// WHERE #fillRow(int[][], int[], int) =
void fillRow(int[][] bag, int[] row, int i) {
bag[i] = new int[row.length];
System.arraycopy(row, 0, bag[i++], 0, row.length);
}
Demo
import java.util.Arrays;
/** Utilities for 2D arrays. */
public class Array2dUtils {
public static void main(String[] args) {
int[][] bag = new int[][] {
{ 0 },
{ 1, 1 },
{ 2, 2, 2 }
};
int[] row1 = new int[] { 3, 3};
int[] row2 = new int[] { 4 };
int[][] biggerBag = appendRows(bag, row1, row2);
System.out.println("Bag:\n" + toString(bag));
System.out.println("Bigger Bag:\n" + toString(biggerBag));
}
/** Append one or more rows to a 2D array of integers. */
public static int[][] appendRows(int[][] bag, int[]... rows) {
int[][] extendedBag = new int[bag.length + rows.length][];
int i = 0;
for (int[] row : bag) { fillRow(extendedBag, row, i++); }
for (int[] row : rows) { fillRow(extendedBag, row, i++); }
return extendedBag;
}
/* fill i-th item of the bag */
private static void fillRow(int[][] bag, int[] row, int i) {
bag[i] = new int[row.length];
System.arraycopy(row, 0, bag[i++], 0, row.length);
}
/** Pretty-prints a 2D array of integers. */
public static String toString(int[][] bag) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bag.length; ++i) {
sb.append(Arrays.toString(bag[i])).append("\n");
}
return sb.toString();
}
}
$ javac Array2dUtils.java
$ java -cp "." Array2dUtils
Bag:
[0]
[1, 1]
[2, 2, 2]
Bigger Bag:
[0]
[1, 1]
[2, 2, 2]
[3, 3]
[4]