Copying array elements within multidimensional arrays in Java - java

So I'm having some trouble with this in java. This method is supposed to take in two String arrays which are multidimensional. This method is supposed to return a a copy String array. Now these two arrays that are being sent to the copy method are going to have randomly generated lengths within the arrays. I am trying to see if array2 is smaller than array and if it is then array will be assigned the length of array2 and I want to copy elements from array into array2. If it is the opposite with array2 being bigger than array then I would like to copy the elements from array into array2 and then the REMAINING spots in array2 will get filled with an *. Now the issue is I keep getting runtime errors with out of bounds for the index. It is specifically the lines that I have indicated with double asterisks below(within for loops) that are giving me issues. What could I do to solve the issue.
public static String[][][] copy(String[][][] array, String[][][] array2){
if(array2.length < array.length){
array = new String[array2.length][array2.length][array2.length];
for(int i = 0; i < array2.length; i++){
for(int j = 0; j < array2[i].length; j++){
for(int k = 0; k < array2[i][j].length; k++){
**array2[i][j][k] = array[i][j][k];**
}
}
}
return array2;
}
if(array2.length > array.length){
for(int i = 0; i < array.length; i++){
for(int j = 0; j < array[i].length; j++){
for(int k = 0; k < array[i][j].length; k++){
**array2[i][j][k] = array[i][j][k];**
}
}
}
for(int i = array.length - 1; i < array2.length; i++){
for(int j = array[i].length - 1; j < array2.length; j++){
for(int k = array[i][j].length - 1; k < array2.length; k++){
array2[i][j][k] = "*";
}
}
}
return array2;
}
return array;
}

You assume that each dimension of the array is of equal size.
But you cannot even assume that two sibling arrays are of equal size.
What I mean is, that array = new String[array2.length][array2.length][array2.length]; is nonsense and at least in two ways.
You probably want to have array2 = new String[array.length][][], because if you reassign array you will just copy nulls around. And for the lengths of the other dimensions you have to do the same comparisons and resizings, especially if you did not reassign the array2. If you did, then you have to create the sub-level arrays afresh anyway.

Related

How do I copy a 2d array with an unknown column size in Java?

For school work I need to write a constructor for a class that contains a 2-dimensional array of integers. The constructor copies a passed in two-dimensional array. Below is the code I have so far. The current issue I have is how to initialize the array when the "column" size of the passed in array is unknow. The issue I think I am having is when creating and initializing the array. The length of the inner and out array is unknown.
public IntMatrix (int[][] array)
{_matrix = new int [array.length][array.length-1].length];
for (int i = 0; i < array.length; i++) {
for(int j=0; j < array[i].length; j++)
_matrix[i][j]=array[i][j];
}
}
As I said in a comment, what you have is an array of arrays:
public IntMatrix(int[][] array) {
matrix = new int[array.length][];
for (int i = 0; i < array.length; i++) {
matrix[i] = new int[array[i].length];
for(int j=0; j < array[i].length; j++) {
matrix[i][j] = array[i][j];
}
}
}
You can always determine the size of an array via myArray.length, so you can allocate for each row/column as you iterate through.
A thought, however. Is it acceptable to simply store the reference to the array that you're passed ? Will it change outside your class ? If not, then that might be a simple solution if you don't have to recreate the array internally.

Combining elements in jagged 2D arrays into one new jagged 2D array (Deep Copy issue)

Given two jagged arrays: a & b where a + b will always have the same # of rows:
int[][] a = { {1,2}, {4,5,6} };
int[][] b = { {7}, {8,9,0} };
how exactly can I manipulate a new jagged array c to return:
{ {1,2,7}, {4,5,6,8,9,0} }?
Here's what I have so far:
int[][] c = null;
for(int i = 0; i<a.length; i++){
c = new int[a.length][a[i].length + b[i].length];
}
//rest of my code for assigning the values into the appropriate position works.
The trouble arises, as you all can see, that I am performing a deep copy, which, on the second iteration of the for-loop, is setting ALL rows to a length of the length of the current row on the step of the iteration.
Flaw in your approach
You are creating a new 2D array object each iteration of your loop. Each time through, you are reassigning c, thus throwing out all of your previous work. Additionally, placing a number in both set of brackets at the same time results in each row having the same length.
Using your example, the first time through the loop, c is assigned to a 2D array with two rows, each of length three. The second time through the loop, you throw out your previous 2D array and create a new one having two rows, each of length six.
But what you need to be doing is creating a new row each time through the loop, not the entire 2D array.
Solution
First, we create a 2D array called c and specify that it has a.length rows. We don't put a value in the second bracket, because that would indicate that all of the rows are of the same length. So at this point, c does not know about row length. It just knows how many rows it can have. Keep in mind: c doesn't actually have any rows yet, just a capacity for a.length rows.
Next, we must create the rows and assign a length/capacity to them. We set up our loop to run as many times as there are rows. The current row index is denoted by i, and therefore, c[i] refers to a specific row in the 2D c array. We use new int[] to create each individual row/array, but inside the brackets, we must specify the length of the current row. For any row c[i], its length is given by the sum of the lengths of a[i] and b[i]; that is, a[i].length + b[i].length.
What we are left with is an array c that contains rows/arrays, each with a set length/capacity that matches the sum of the corresponding rows lengths in a and b.
Keep in mind that c still does not contain any integer values, only containers that are of the correct size to hold the values in a and b. As you mentioned, you already have code to populate your array with values.
int[][] c = new int[a.length][];
for (int i = 0; i < a.length; i++) {
c[i] = new int[a[i].length + b[i].length];
}
When initialize Java 2D array, lets consider it as a table; you only have to give the number of rows and in each row of your table can have different number of columns.
Eg. Say we have a 2D array call c defined as follows,
int[][] c = new int[10][];
It says you defined c contains 10 of int[] elements. But in order to use it you have to define the number of columns each row has.
Eg. Say we have 3 columns in the second row
int c[1] = new int[3];
So in this example you have to add the column values of 2D arrays a and b to calculate the resultant array which is c.
c[i] = new int[a[i].length + b[i].length];
This will give you what you expected.
int[][] a = { {1,2}, {4,5,6} };
int[][] b = { {7}, {8,9,0} };
int[][] c = new int[a.length][];
for(int i = 0; i<a.length; i++){
c[i] = new int[a[i].length + b[i].length];
for (int j=0;j< a[i].length; j++) {
c[i][j] = a[i][j];
}
int length = a[i].length;
for (int j=0;j< b[i].length; j++) {
c[i][length+j] = b[i][j];
}
}
Try c[i] = new int[a[i].length + b[i].length]
int[][] c = new int[a.length][];
for(int i = 0; i < c.length; i++){
c[i] = new int[a[i].length + b[i].length];
int x = 0;
for (int num : a[i]) {
c[i][x] = num;
x++;
}
for (int num : b[i]) {
c[i][x] = num;
x++;
}
}
or even simpler...
int[][] c = new int[a.length][];
for(int i = 0; i < c.length; i++){
c[i] = new int[a[i].length + b[i].length];
System.arraycopy(a[i], 0, c[i], 0, a[i].length);
System.arraycopy(b[i], 0, c[i], a[i].length, b[i].length);
}
Try this one:
int[][] c = new int[a.length][];
for(int i = 0; i<a.length; i++){
c[i] = new int [a[i].length + b[i].length];
int j;
for(j=0; i < a[i].length; j++){
c[i][j] = a[i][j];
}
for(int k=0; i < b[i].length; k++){
c[i][j+k] = b[i][j];
}
}
public static void main(String [] args) {
int[][] a = { {1,2}, {4,5,6} };
int[][] b = { {7}, {8,9,0} };
int[][] c = null;
for(int i = 0; i<a.length; i++){
c = new int[a.length][a[i].length + b[i].length];
}
for(int i = 0; i<a.length; i++){
for (int j = 0; j < a[i].length+b[i].length; j++) {
if(j< a[i].length){
c[i][j]=a[i][j];
}
if(j< a[i].length+b[i].length && j>= a[i].length){
c[i][j]=b[i][j-a[i].length];
}
}
}
for(int i = 0; i<a.length; i++){
for (int j = 0; j < a[i].length+b[i].length; j++) {
System.out.print(c[i][j]);
}
System.out.println();
}
}
This works in my system ...........

Java - Filling multidimensional (2d) ArrayList like a 2d array

A while ago before I got used to object object oriented programming I created a basic TicTacToe game and to create the board I used an array.
The code is a complete mess because I didn't properly understand how to use objects, but I did initialize the board correctly:
char[][] board = new char[3][3];
for (int i = 0; i < board.length; i++){
for (int j = 0; j < board[i].length; j++){
board[i][j] = '[]' //or something like that...don't remember exactly
}
}
My question is how would you this with an ArrayList?
ArrayList <ArrayList<Character>> board = new ArrayList(); // this initialization is not
// wrong using Java 8 but for earlier versions you would need to state the type on both
//sides of the equal sign not just the left
for (int i = 0; i < board.size(); i++){
for (int j = 0; j < board.get(i).size(); j++){
board.get(i).get(j).add('[]');
}
}
but that does not work.
It does not have to be exactly like this, I just generally want to understand how to handle multidimensional ArrayLists.
-thanks
Unlike arrays, you can't initialize an entire ArrayList directly. You can specify the expected size beforehand (this helps performance when you are using very large lists, so it is a good practice to do it always).
int boardSize = 3;
ArrayList<ArrayList<Character>> board = new ArrayList<ArrayList<Character>>(boardSize);
for (int i = 0; i < boardSize; i++) {
board.add(new ArrayList<Character>(boardSize));
for (int j = 0; j < boardSize; j++){
board.get(i).add('0');
}
}
The main difference is that in your original code you had a multi-dimensional array of primitives (in this case, char) and all you had to do was assign a new primitive value to each slot in the array.
However what you want now is an ArrayList of (ArrayList of Character). When you create the ArrayList it is empty. In order to procede you are going to need to fill it with several (ArrayList of Character) before you can begin to start adding Characters themselves.
So for example,
ArrayList <ArrayList<Character>> board = new ArrayList<>();
for (int i=0; i<3; i++) {
board.add(new ArrayList<Character>());
}
Now you can start adding Characters to your lists:
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
board.get(i).add('A');
}
}
Hope this helps.
First you have to initialize the ArrayList in your first line correctly and than you have to initialize an new ArrayList in each run of your first loop:
ArrayList <ArrayList<Character>> board = new ArrayList<ArrayList<Character>>();
for (int i = 0; i < 3; i++){
ArrayList<Character> innerList = new ArrayList<Character>();
board.add(innerList);
for (int j = 0; j < 3; j++){
innerList.add('[');
}
}

How can i split an 1D array to 2D array with specific size of column?

I have a one dimensional array arr1D[i] and i want it to convert in two dimensional array arr2D[i][j], where the size of column in 2D array should be 512 and row size can be any thing. For example, if i have 1D array with size arr1D[1024] then the corresponding 2D array should be arr2D[2][512].
int len=arr1D.length();
if(len%512 !=0))
len= len/512 +1;
else
len=len/512;
int arr2D= new int[len][512];
int k=0;
for(int i=0; i<len-1; i++)
{
for(int j=0; j<512; j++)
{
arr2D[i][j]=arr1D[k];
k++;
if (k==arr1D.length())
break;
}
}
How about two forloops to copy them:
2darray[][];
size1d = 1024;
num_colums = 512;
num_rows = size1d/num_colums;
for(i = 0; i < num_rows; i++){
for(j = 0; j < num_colums; j++){
2darray[i][j] = 1darray[i*num_colums+j];
}
}
This is just pseudocode, but with a few tweeks it should work; hope it helps :-)
Well you can easily create it by doing
yourtype arr2D[][] = new yourtype[arr1D.length/2][512] // yourtype :=[int,float,..]
Now all depends on you, how you are going to copy those elements of arr1d in arr2d

Java 2-D selection sort

I am preparing for an exam, and we are likely to be tasked with sorting a two dimensional array of ints. Sorted meaning the first row, first column is the lowest and the last row, last column is the highest.
I approached the task by creating a 1-D array, and then populating it with all the values in the 2d array. Then, I passed it through a sorting method. Finally, I wrote each value of the sorted array back into the 2d array and returned it.
This sort of worked, as you can see from the output below. I am confused as to where my process is breaking down, I would appreciate any input.
Input:
int[][] nums = {{1,5,9},{8,9,3},{0,7,6}};
output:
0 0 0
0 0 0
0 0 1
public int[][] sort2D(int[][]nums){
int[] temp = new int[((nums.length+1)*(nums.length+1))];//make one long array
for(int i =0; i<nums.length; i++){ //populate
int counter = 0; //indices for long array
for(int j = 0; j<nums[i].length; j++){
System.out.println(temp[counter]);
temp[counter] = (int)nums[i][j];
counter++;
}
}
temp = sort(temp); //sort it (verified code)
for(int i = 0; i<nums.length; i++){ //reverse the above process
int counter = 0;
for(int j = 0; j<nums.length; j++){
nums[i][j] = temp[counter];
counter++;
}
}
return nums;
}
The first thing I think you're doing wrong is this:
int[] temp = new int[((nums.length+1)*(nums.length+1))];//make one long array
nums.length +1 = 4 in your case. you are copying your 3*3 array into a 4*4 array.
This has the funny effect of adding 5 0's to your result. (temp[9] till temp[15] will be 0 filled)
After you sort, these 0's will show up
the place where your code breaks down is:
for(int i =0; i<nums.length; i++){ //populate
>> int counter = 0; //indices for long array
for(int j = 0; j<nums[i].length; j++){
System.out.println(temp[counter]);
temp[counter] = (int)nums[i][j];
counter++;
}
}
You initialize the counter to 0 every time you go through one of your outer arrays.
this means that on the 3rd pass (last array) you overwrite temp[0], temp1 and temp[2] with nums[2][0], nums2, nums[2][2]
I assume in your actual code, you do
int counter = 0; //indices for long array
for(int i =0; i<nums.length; i++){ //populate
for(int j = 0; j<nums[i].length; j++){
System.out.println(temp[counter]);
temp[counter++] = (int)nums[i][j];
}
}
You could also use System.arrayCopy, especially if you know the length and suchlike.

Categories