Filling in 2D Array into 3D Array in Java - java

I want to write a Method where I get a 3x6 workingArray (but might also be 3x5, 3x4...) and a 3x3 (maybe also different size) filteringArray and make an 3D Array (holdArrays) where I put in the first Array to make a square (in this case 3x3), then move one position and put in another 3x3, till the last column of workingArray has been covered.
Somehow I get an nullPointerException in '//affected line' and I can't see why. So I wonder if I do this the right way and I haven't found resources for how to put 2D Arrays into 3D Array.
Example:
1 2 3 4 1 2 3 2 3 4
5 6 7 8 to 5 6 7 and 6 7 8
9 1 2 3 9 1 2 1 2 3
private static void filtering(double[][] workingArray, double[][] filteringArray) {
// creating amount of holdArrays to work with filterArray
double[][][] holdArrays = new double[workingArray.length - filteringArray.length + 1][filteringArray.length][];
// filling in the parted workingArray into holdArrays
for (int i = 0; i < holdArrays.length; i++) {
for (int j = 0; j < filteringArray.length; j++) {
for (int k = 0; k < filteringArray[j].length; k++) {
holdArrays[i][j][k] = workingArray[j][k]; //affected line
}
}
}
}

The size of the last dimension is not specified. And since the line
holdArrays[i][j][k] tries to access the kth element which is not there, it throws a Null Pointer Exception.
double[][][] holdArrays = new double[workingArray.length - filteringArray.length + 1][filteringArray.length][];

Related

Why do my loops stop early when iterating through and array

So I am trying to iterate through a 4 by 3 array of objects and set the value of each object according to user input, but I've run into a problem where the iteration through the array stop at 6 instead of the total 12. I've tried a few way of writing the iterators but they always fail. This is the code.
Card[][] field = new Card[3][2];
void setvals(){
Scanner scanner = new Scanner(System.in);
for(int row= 0; row < field.length; row++){
for(int col = 0; col < field[row].length; col++) {
String input = scanner.nextLine();
field[row][col] = new Card();
field[row][col].makeCard(input);
}
}
}
I have also tried <= instead of < but then it gives me array index out of bounds. I have no clue what the problem is.
Your problem is with the array:
Card[][] field = new Card[3][2];
You want the array to be 4 x 3, then set the dimensions as so:
Card[][] field = new Card[4][3];
The reason your code is not working, is since you currently have a 2 x 3 array, evaluating to 6 iterations. A 4 x 3 array would evaluate to 12 iterations, as you want.
You say:
So I am trying to iterate through a 4 by 3 array of objects...
And here is your array: Card[][] field = new Card[3][2];.
That is not a 4x3 array. It is a 3x2 array, which means there should be 6 iterations in your loop, which is what is happening. There is no error here.

Java Copying Data from Array Rather than Reference

In the following code, I am trying to duplicate the 2d array 'cur,' swapping two values in the array, and eventually add it to an arraylist I will be using later in the program. My problem is, every time I switch these values in the array 'temp' (has the cloned values of 'cur') it also switches the values in the array 'cur.' I'm confused because I have tried clone(), Arrays.copyof, even made a new constructor for the PuzzleNode class that takes the values from cur, yet every time 'cur' doesn't reset to its original value when the iteration of the loop finishes. Any help is much appreciated.
Here's the code:
//generate the puzzles and swap the tiles
for (int i = 0; i < possibleSwaps.size(); i++) {
//stores the 2d array of Nodes
PuzzleNode temp = new PuzzleNode();
//instantiate the 2d array and populate it with values of cur
temp.puzzle = new Node[cur.puzzle.length][cur.puzzle[0].length];
for (int j = 0; j < cur.puzzle.length; j++) {
temp.puzzle[j] = cur.puzzle[j].clone();
}
for (int j = 0; j < cur.puzzle.length; j++) {
for (int k = 0; k < cur.puzzle[0].length; k++) {
if (temp.puzzle[j][k].value == possibleSwaps.get(i).value) {
//switch the values, values should always be distinct
int prev = temp.puzzle[zeroNode.x][zeroNode.y].value;
temp.puzzle[zeroNode.x][zeroNode.y].value = possibleSwaps.get(i).value;
temp.puzzle[possibleSwaps.get(i).x][possibleSwaps.get(i).y].value = prev;
}
}
}
//prints out the 2d array that should be the same everytime. But isn't
printPuzzle(cur.puzzle);
}
Example of Print Out:
(Original 2d array I want to always have)
1 2 3
4 6 8
7 [] 5
(Switched the [] and the 6, I NEED the [] to remain where it originally was in the previous iteration, so it can be swapped with the 5 and 7 in the next iterations)
1 2 3
4 [] 8
7 6 5
(Stays where it was swapped in the previous iteration)
1 2 3
4 [] 8
7 5 6
1 2 3
4 [] 8
5 7 6

Single array re-indexing for table formatting

I am looking for a more elegant solution to the following scenario (language doesn't matter, Java is fine, but I am currently in C#). Suppose a linear array is coming in and being displayed as a table with X items per row (For instance, 9 items coming in at 3 items per row, so 3 rows of 3). If the array is being indexed 0 through 8, it is currently displayed as such:
6 7 8
3 4 5
0 1 2
So, the elements are displayed left to right, bottom to top. I would like to rearrange this to be displayed top to bottom, like this:
0 1 2
3 4 5
6 7 8
This requires reordering the array so that the new array's indexes are [6,7,8,3,4,5,0,1,2], with respect to the original's indexes. My current (untested) solution is the following: assume the array to be returned is 'array' and a temporary copy is 'temp', and the 'cols' variable is already the number of items per row.
int rows = (array.Length + cols - 1) / cols; //ceiling function to determine rows needed
int pos = array.Length - cols; //starting position in index transfer
int offset = 0; //needed when negative index reached
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (pos + j >= 0)
array[cols * i + j - offset] = temp[pos + j]; //assign values of temp to array
else
++offset; //takes care of negative indeces
}
pos -= cols;
}
return array;
The problem is this code is quite unreadable and possibly inefficient because of the double loop, though I don't expect many more than 9 items to come through. Is there a more elegant solution to this using slicing up the array, reversing, or anything that isn't so difficult to read? It's just a fun little problem I've been thinking about for an issue at work. Anybody's input is appreciated, thanks!
It is worth noting that potentially uneven tables can be created (For instance, 9 elements with 4 items per row creates 2 rows of 4, one row of 1. The 'offset' variable is used to protect negative array indexing if this is the case).
This is what I came up with: it doesn't sort your original array at all, but every inner loop starts at a computed starting-index based on the row you're printing. Let me know if you have any questions. This isn't specific to you, more specific to your situation, but the concept and functionality is there.
int[] array = new int[9] { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
int rows = 3;
int cols = 3;
int count = 0;
for (int x = 1; x <= rows; x++)
{
int startingPos = array.Length - (x * rows);
for (int y = cols; y > 0; y--)
{
Console.Write(array[startingPos] +", ");
count++;
startingPos++;
}
Console.WriteLine();
}

Break large 2D array into multiple smaller 2D array using JAVA

I have a 2D array which consist of image pixels which its size depends on the size of the input image. I need to break it into smaller 9x9 arrays. To give a clearer picture, I try to illustrate the situation:
//The number of rows and columns of the smallerArray will look something like this:
It should copy them from the imagePixels array iterating through each 8 columns, then move on to the next 8 rows.
1st small 2nd small 3rd small and so on..
array: array: array:
012345678 91011121314151617 181920212223242526 ....
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
Then move on to next 8 rows:
012345678 91011121314151617 181920212223242526 ....
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
14 14 14
15 15 15
16 16 16
17 17 17
.
.
.
I have done the following code but could not get my logic right. How can I stop the iteration:
Copy up until the 9th column or row, store it in an array, resume copying on the 10th column/row, stop when it reaches 9 column/row after, store it in another array, and keep on doing that till it finishes copying the imagePixels array.
I tried to store the arrays in an ArrayList so it would be easier for me to manipulate and do calculation stuffs with all the smallerArrays.
ArrayList<double[][]> collectionofSmallArrays = new ArrayList();
double[][] imagePixels = new double[1600][1000]; //Lets say this is the size of the image
double[][] smallerArray = new double[9][9];
for(int a = 0; a<smallerArray.length; a++)
{
for(int b =0; b<smallerArray[a].length; b++)
{
for(int c=0; c<imagePixels.length; c++)
{
for(int d=0; d<imagePixels[c].length; d++)
{
smallerArray[a][b] = imagePixels[c][d];
...(code to stop the iteration if it reaches 9, store it in array then resume where it stops with another new array)
collectionofSmallArrays.add(smallerArray);
}
}
}
}
Can anyone work around the code to achieve the expected result? Appreciate it.
You should probably provide more context information. Saying that an array of double values represents pixels sounds dubios. If you are working with images, then you might find solutions on a completely different level of abstraction (I'm thinking about BufferedImage#createSubImage here).
However, to answer the question: You should break the task up into smaller parts. Particularly, it might be easier to implement two methods:
One method that receives an input array, some coordinates, and an output array, and that copies the data from the specified coordinates of the input array to the output array
One method that calls the above mentioned method with the appropriate coordinates to split the whole array into the parts of the desired size.
In pseudocode:
for (each coordinates (9*r,9*c)) {
copy the rectange (9*r,9*c)-(9*r+9,9*c+9) of the input array into an array
A very simple implementation/test is shown in the following example. Note that this could be generalized and improved, but I think it shows the basic idea:
import java.util.ArrayList;
import java.util.List;
public class SubArrayTest
{
public static void main(String[] args)
{
double inputArray[][] = createInputArray(160, 100);
System.out.println("inputArray: "+toString(inputArray));
List<double[][]> subArrays = createSubArrays(inputArray, 9, 9);
for (double subArray[][] : subArrays)
{
System.out.println("subArray:\n"+toString(subArray));
}
}
private static List<double[][]> createSubArrays(
double inputArray[][], int subRows, int subCols)
{
List<double[][]> subArrays = new ArrayList<double[][]>();
for (int r=0; r<inputArray.length; r+=subRows)
{
for (int c=0; c<inputArray[r].length; c+=subCols)
{
double subArray[][] = new double[subRows][subCols];
fillSubArray(inputArray, r, c, subArray);
subArrays.add(subArray);
}
}
return subArrays;
}
private static void fillSubArray(
double[][] inputArray, int r0, int c0, double subArray[][])
{
for (int r=0; r<subArray.length; r++)
{
for (int c=0; c<subArray[r].length; c++)
{
int ir = r0 + r;
int ic = c0 + c;
if (ir < inputArray.length &&
ic < inputArray[ir].length)
{
subArray[r][c] = inputArray[ir][ic];
}
}
}
}
//===Test methods=========================================================
private static double[][] createInputArray(int rows, int cols)
{
double array[][] = new double[rows][cols];
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
array[r][c] = r*100+c;
}
}
return array;
}
private static String toString(double array[][])
{
String format = "%7.1f";
StringBuilder sb = new StringBuilder();
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
sb.append(String.format(format, array[r][c])+" ");
}
sb.append("\n");
}
return sb.toString();
}
}
Side notes:
You should always declare variables with their interface type. This means that you should not write
ArrayList<String> x = new ArrayList<String>();
but always
List<String> x = new ArrayList<String>();
In the posted code, you seemed to always add the same instance of the sub-array to the list. This means that in the end you would have many instances of the same array in the list, all with the same content. Somewhere in between you have to create a new double[9][9] array.
smallerArray[a][b] = imagePixels[c][d] line looks strange. You reuse same array instance. Your output array list will contain multiple reference to same array.
You cannot reuse smallerArray. Create the instance inside the for loop and store the size in a constant.
I think a map with some corner coordinates as a key would be far better than a list for storing your results.
What happens if the length or width or your image is not divisible by 9?

null last element in 2D array

I have the following 2D array:
private static Object[][] myClass = new Object[6][5];
and I am looking to null the last element in the array (myClass[lastIndex][all indexes] = null) using the following code:
for(int y = 0;y < 5;y++) {
myClass[5][y] = null;
}
However it seems to be deleting the last two elements in the array, what is causing this?
EDIT:
array print out before delete:
one
1
1
1
1.0
two
2
2
2
2.0
three
3
3
3
3.0
four
4
4
4
4.0
five
5
5
5
5.0
six
6
6
6
6.0
After "deleteing" element one(In practise I want to "delete" element one by copying all the elements down one index and setting the last to null):
two
2
2
2
2.0
three
3
3
3
3.0
four
4
4
4
4.0
five
5
5
5
5.0
null
null
null
null
null
null
null
null
null
null
My full delete code:
public void deleteStudent(int studentChoice) {
for(int i = studentChoice;i < myClass.length - 1;i++) {
myClass[i] = myClass[i+1];
}
myClassCount = myClassCount - 1;
for(int y = 0;y < 5;y++) {
myClass[5][y] = null;
}
}
int studentChoice is the index of the array.
myClassCount is a variable that's incremented/de-incremented as elements are added/deletted
This is a subtle problem:
When you copy down, the references are copied, not the values in the array so that in the last step, because you don't overwrite myClass[5], myClass[5] == myClass[4] so that any changes you then make to any element in myClass[5] are replicated in myClass[4] as they are the same object! Therefore when you null each object in myClass[5], you are nulling everything in myClass[4] aswell. This can be avoided by copying the individual values down, rather than just the arrays.
You can copy the values down like this:
for(int i = studentChoice;i < myClass.length - 1;i++) {
for(int y = 0;y < 5;y ++){
myClass[i][y] = myClass[i+1][y];
}
}
As a side note, this behavior can be demonstrated by the following:
Object[] array1 = {1};
Object[] array2 = array1;
array2[0] = 2;
System.out.println(array1[0]);//Prints 2

Categories