I'm new to Java programming and my assignment was to copy the content of 2x2 two dimensional array into the middle 4x6 two-dimensional array. I did it anyway but it doesn't print out the way I wanted and I dont know why. Can someone help me identify the problem in my source program. Thanks in advance
public class Main {
public static void main(String[] args) {
int[][] a = {{11,12},{21,22}};
int[][] b = new int[4][6];
System.out.print("a[][] = \n");
output(a);
System.out.print("\nb[][] = \n");
copy(a,b);
}
static void output(int[][] x) {
for(int i=0; i<x.length;i++) {
for(int j=0;j<x[i].length;j++) {
System.out.printf(" %2d ", x[i][j]);
}
System.out.println();
}
}
static void copy(int[][] source, int[][] destination) {
for(int i=0;i<source.length;i++) {
destination[i]= new int[source.length];
System.arraycopy(source[i], 0, destination[i+1], 2, destination[i].length);
}
output(destination);
}
}
The result should be
a[][]
11 12
21 22
b[][]
0 0 0 0 0 0
0 0 11 12 0 0
0 0 21 22 0 0
0 0 0 0 0 0
but I got
a[][] =
11 12
21 22
b[][] =
0 0
0 0
0 0 21 22 0 0
0 0 0 0 0 0
instead.
You are doing several things wrong:
replacing the destination row with an empty array of source size.
using the destination length instead of the source length
Here is how it should look.
static void copy(int[][] source, int[][] destination) {
for (int i = 0; i < source.length; i++) {
System.arraycopy(source[i], 0, destination[i + 1], 2,
source[i].length);
}
output(destination);
}
I have included a more general solution as follows:
Not all arrays will lend themselves to this kind of copy. I return a boolean if the copy was successful or not. Here are some guidelines.
Copying to center implies the same number of unfilled rows above and below, or the same number of unfilled columns to the left or right. This can be determined by subtracting the smallest dimension from the largest and seeing if the remainder when divided by two equals zero. If so, the copy should succeed and true is returned. Else, an informational message is printed and false is returned.
The starting location of each row or column is determined by subtracting the shorter dimension from the longer one and dividing by two.
The loop iterates over the source array while the System.arraycopy does the work of copying to the destination, incrementing the destination row index.
int[][] arr = { { 11, 12}, { 21,22}};
int[][] dest = new int[4][6];
if (copyToCenter(arr, dest)) {
for (int[] rows : dest) {
System.out.println(Arrays.toString(rows));
}
}
prints
[0, 0, 0, 0, 0, 0]
[0, 0, 11, 12, 0, 0]
[0, 0, 21, 22, 0, 0]
[0, 0, 0, 0, 0, 0]
The copy method.
static boolean copyToCenter(int[][] source, int[][] destination) {
if ((destination.length - source.length) % 2 != 0
|| (destination[0].length - source[0].length) % 2 != 0) {
System.out
.println("Arrays do not lend themselves to required copy");
return false;
}
int firstCol = (destination[0].length - source[0].length) / 2;
int destRow = (destination.length - source.length) / 2;
for (int[] sourceRow : source) {
System.arraycopy(sourceRow, 0, destination[destRow++],
firstCol, source[0].length);
}
return true;
}
Related
Input : arr[] : {1, 2, 3, 4, 5}
ranges[] = { {0, 2}, {0, 3} }
index : 1
Output : 3
Explanation : After first given rotation {0, 2}
arr[] = {3, 1, 2, 4, 5}
After second rotation {0, 3}
arr[] = {4, 3, 1, 2, 5}
After all rotations we have element 3 at given index 1.
Not Able to Understand Why starting from last rotation gives right result but if we start from rotation 0 to last in loop it gives wrong result???
https://www.geeksforgeeks.org/find-element-given-index-number-rotations/
// Java code to rotate an array
// and answer the index query
import java.util.*;
class GFG
{
// Function to compute the element at
// given index
static int findElement(int[] arr, int[][] ranges,
int rotations, int index)
{
for (int i = rotations - 1; i >= 0; i--) {
// Range[left...right]
int left = ranges[i][0];
int right = ranges[i][1];
// Rotation will not have any effect
if (left <= index && right >= index) {
if (index == left)
index = right;
else
index--;
}
}
// Returning new element
return arr[index];
}
// Driver
public static void main (String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
// No. of rotations
int rotations = 2;
// Ranges according to 0-based indexing
int[][] ranges = { { 0, 2 }, { 0, 3 } };
int index = 1;
System.out.println(findElement(arr, ranges,
rotations, index));
}
}
This will give right result but following will produce wrong result.
for (int i = 0; i < rotations; i++) {
// Range[left...right]
int left = ranges[i][0];
int right = ranges[i][1];
// Rotation will not have any effect
if (left <= index && right >= index) {
if (index == left)
index = right;
else
index--;
}
}
Lets us consider given 5 length array A1.
You have applied {0,2} rotation on A1. It is changed to A2.
You have applied {0,3} rotation on A2.. It is changed to A3
Now you are looking for output index 1 in A3 (which is {0,3} rotated on A2).
So Index 1 in A3 = Index 0 in A2 (as per the logic)
Now you are looking for Index 0 in A2 (which is {0,2} rotated on A1)
So Index 0 in A2 = Index 2 in A1 (as per the logic)
Hope this explanation clears why the rotations array is iterated in reverse way.
Not Able to Understand Why starting from last rotation gives right
result but if we start from rotation 0 to last in loop it gives wrong
result???
Because its not supposed to give the same output. The final results depends on the order in which you apply the rotations.
Suppose first you apply {0,3}, the array would be :
4 , 1 , 2 , 3 , 5
Now you apply {0,2}
2 , 4 , 1 , 3 , 5
Clearly the element at index 1 is NOT 3
At 0th index value is 4, so I have to check the value at index 4 and square it and place the value at 0th index without using a temp array:
Index 0 1 2 3 4
Values 4 3 1 2 0
================
Result 0 4 9 1 16
Now I am getting the first two values right, but the last three are not right. My code is as below:
static void Index(int arr[], int n) {
for(int i=0;i<n;i++) {
int index = arr[i];
int value = arr[index];
arr[i]=value*value;
}
}
Below is the output that I am getting:
Original Array
4 3 1 2 0
Array after Squaring
0 4 16 256 0
Can anyone help me out here as to what am I doing wrong?
Assuming the numbers are within range [0, 46341), we can store both the old and the new values in the array during the process (as 32 bits are enough). Then after the first loop we do another one to discard the old values and square the new ones.
// assume array[i] is within range [0, 46341) for any i
static void f(int[] array) {
for (int i = 0; i < array.length; i++) {
int j = array[i] & 0xffff; // get old value
array[i] = array[j] << 16 | j; // put new and old values
}
for (int i = 0; i < array.length; i++) {
int j = array[i] >>> 16; // get new value
array[i] = j * j; // put new value squared
}
}
NOTE: This approach is valid only if length of array is less than 10.
I have completed this code using only one loop without using any extra space.
Although, I have set a flag to run the complete loop twice.
If you do not have any constraint of using one loop, you can avoid using the flag and simply use two loops.
Approach:
Index 0 1 2 3 4
Values 4 3 1 2 0
Updated value 04 23 31 12 40
You must have got the idea what I did here.
I put the values at tens place whose square is to be displayed.
Now you have to just have to iterate once more and put the square of tens place at that index
Here's the code:
void sq(int arr[], int n){
bool flag = false;
for(int i=0; i<n; i++){
if(!flag){
if(arr[arr[i]] < 10){
arr[i] += (arr[arr[i]] * 10);
}
else{
arr[i] += ((arr[arr[i]]%10) * 10);
}
}
if(i==n-1 && !flag){
i=0;
flag = true;
}
if(flag)
arr[i] = (arr[i]/10) * (arr[i]/10);
}
}
It is in C++.
The problem is you are changing the values in your original array. In you current implementation this is how your array changes on each iteration:
{4, 3, 1, 2, 0}
{0, 3, 1, 2, 0}
{0, 4, 1, 2, 0}
{0, 4, 16, 2, 0}
{0, 4, 16, 256, 0}
The problem is you still need the values stored in the original array for each iteration. So the solution is to leave the original array untouched and put your values into a new array.
public static void index(int arr[]) {
int[] arr2 = new int[arr.length];
for(int i=0;i<arr.length;i++) {
int index = arr[i];
int value = arr[index];
arr2[i]=value*value;
}
}
Values of arr2 in revised process:
{0, 0, 0, 0, 0}
{0, 0, 0, 0, 0}
{0, 4, 0, 0, 0}
{0, 4, 9, 0, 0}
{0, 4, 9, 1, 0}
{0, 4, 9, 1, 16}
Currently I have an arrayList which contains several value pairs. I'm trying to print them in matrix format as shown in the example below. Every odd number is the location in the matrix and the following number is the value. The location goes up as in a counter and if the number doesn't exist in the array a 0 is placed in it's location. Bit tricky to explain.
arraylist contains (1, 10, 2, 90, 4, 9, 7, 2, 11, 4, 14, 45)
Output:
0 10 90 0
9 0 0 2
0 0 0 4
0 0 45 0
I've tried:
int position, value;
int size = 16;
for (int i = 0 ; i < size ; i += 2) {
position = matrix.get(i);
if(position == i){
value = matrix.get(i+1);
System.out.print(value);
} else {
System.out.print("0");
}
}
You want to read numbers in your array not one after one, but two after two. Try this (this is not enough to solve your problem, but this will help) :
for (int i = 0 ; i < size ; i += 2) {
int position = matrix.get(i);
int value = matrix.get(i+1);
... // Deal with them
}
To actually fill the matrix with the right values, you should use a Map<Integer, Integer>.
You can increment by more than 1 in a for loop, e.g.
for(int i = 0, size = matrix.size( ); i < size ; i = i+2)
{
...
}
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]
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("");
}
}
}