Assume that I already have a 2D int value[i][j]. This works well and I can store a single int in each index. Now I want to add a second array int data[i][j] so I can store multiple int data in it. Am I approaching it correctly?
For example in a Sudoku situation:
value[0][0] = 0
But in an other grid I have all possible values in each index
data[0][0] = {1,2,3,4,5,6,7,8,9}
Is it possible to do that? If so what should I do with my data? I'm really confused about arrays, multi-dimensional arrays, ArrayLists, etc. I'm unsure which to use.
For example:
Values {1,2,3},{4,5,6},{7,8,9}
In an 3x3:
1,2,3
4,5,6
7,8,9
Data{1,2,3,4,5,6,7,8,9}
Which I want to store it now in each grid and will have a method to remove from that list in later steps because I'm cancelling those possibilities in that grid. And the data in data{} doesn't have to be shown to the user.
I hope this will clear to some extent
Internally, Java stores 2 dimensional arrays as an array of arrays:
Suppose you have
int [][] nums = new int[5][4];
The above is really equivalent to a 3-step process:
int [][] nums;
// create the array of references
nums = new int[5][];
// this create the second level of arrays
for (int i=0; i < nums.length ; i++)
nums[i] = new int[4]; // create arrays of integers
Simply use boolean[] for possible choices. You could use Set (http://docs.oracle.com/javase/7/docs/api/java/util/Set.html), but for a small pool of fixed size with boolean options only, Set is an overkill (mainly due to code overhead).
Next thing is, that the basic principle of OOP (and Java is, or at least should be OOP) is that you should group data into objects/classes based on their functionality. If you're trying to aggregate a cell in a grid, you should create a grid (2D array) of objects, not a couple of int or boolean (or whatever) arrays.
First create a class, e.g.
class Cell {
final int POSSIBILITES = 9;
int actual_value;
boolean[] possible_values = new boolean[POSSIBILITES]; // for each number
Cell( int actual_value ) {
this.actual_value = actual_value;
for( int i = 0; i < POSSIBILITES; i++ )
possible_values[i] = true;
}
}
and then initialize/instantiate an array of objects
//...
final int X_SIZE = 9, Y_SIZE = 9;
Cell[][] cells = new Cell[X_SIZE][Y_SIZE];
for( int i = 0; i < X_SIZE; i++ )
for( int j = 0; j < Y_SIZE; j++ )
cells[i][j] = new Cell( somevalue );
//...
And then access them by, for example
//note: it's more proper to use getter/setter pattern, so this is only a crude example
if ( cells[3][6].actual_value = 7 )
do_something();
cells[1][2].possible_values[0] = false; // we're numbering from 0 to 8, so value 1=> index 0, 2=>1... 9=>8
cells[1][2].possible_values[4] = true;
Yes, it is possible. For that I'd recommend a boolean[][][] where, for example, theArray[6][3][8] is a boolean indicating whether the number 8 is included in the cell at row 6, column 3.
Related
Currently the code I have adds a set of attributes into the list below, and returns one giant ArrayList with 70 attributes. I'd like those 70 attributes split into 5 Arrays that represent the 5 columns of the dataset - so I can more easily visualise and then compare the data repetition inside each.
I cannot use an external library like guava since its for an assignment so I can't add any extra files into the project.
I found methods that only work to partition byte lists, and a List<> generic method which I could not make work.
Any suggestions? I know this should be so simple but I cannot find the solution
ArrayList<String> allRows = new ArrayList<String>();
for (int ex = 1; ex < dataExamples; ex++) {
for( int ats = 0; ats < dataAttributes; ats++){
allRows(data[ex][ats]);
}
}
System.out.println(allRows);
This is a simple problem of iterating through the data in the correct manner.
I am unsure if you want Horizontal insertion into the 2d array or vertical insertion. So I've added both, just uncomment the one you want.
// Create fake data
ArrayList<Integer> allRows = new ArrayList<Integer>();
for (int i = 0; i < 70; i++)
allRows.add(i);
System.out.printf("All Data: %s%n", allRows.toString());
// Create 2 Dementional Array
ArrayList<ArrayList<Integer>> twoDRows = new ArrayList<ArrayList<Integer>>();
// Add the 5 rows
for (int i = 0; i < 5; i++)
twoDRows.add(new ArrayList<Integer>());
// Split allRows
for (int i = 0; i<allRows.size(); i++) {
int rowToAddTo;
// Horizontal
rowToAddTo = i/(allRows.size()/twoDRows.size());
// Vertical
rowToAddTo = i%twoDRows.size();
twoDRows.get(rowToAddTo).add(allRows.get(i));
}
// Pretty-ish print
for (ArrayList<Integer> array:twoDRows)
System.out.println(array);
Assuming your array contains your column elements evenly distributed (that is elements 0,5,10,... belong to the same column; 1,6,11,.. to another column, etc.) you can use the mod operation (%) to separate those elements, something like this:
ArrayList<ArrayList<String>> listOfLists = new ArrayList<ArrayList<String>>();
//populate listOfLists
for(int i = 0; i < numberOfColumns; i++){
listOfLists.add(new ArrayList<String>());
}
for(int index = 0; index < totalElements; index++){
//Obtain number of correponding column with mod
int remainder = index % numberOfColumns;
//Insert your element into that corresponding array in listOfLists
listOfLists.get(remainder).add("YOUR ELEMENT");
}
Notice that numberOfColumns is the total number of columns you have, being it 5 or something else.
You may also want to check this answer regarding the sublist() method. Which seems to be also similar to your question.
Cheers
EDIT
Changed the code so it will match any number of columns and add your element to the corresponding array.
I have a JLabel array that starts with an integer number of elements. How can I remove an certain number of elements from the array? For example, every time the int is updated:
int i = 21;
i = i - removedElements
How can I update the array to contain that many elements, instead of creating an entirely new array with the desired number of elements?
As others have already mentioned, List is the way to go here since it is specifically designed for adding and or deleting elements.
However if you would prefer to use the JLabel Array you already have in established then you will need to realize that the only way to delete an element from that array is to actually create another array with the desired element to delete excluded from it then return it into the original array. Below I have supplied a simple method named deleteJLabelFromArray() that can do this for you:
public static JLabel[] deleteJLabelFromArray(JLabel[] srcArray, int... indexesToDelete) {
int counter = 0;
JLabel[] newArray = new JLabel[srcArray.length - indexesToDelete.length];
for (int i = 0; i < srcArray.length; i++) {
boolean noGo = false;
for (int j = 0; j < indexesToDelete.length; j++) {
if (i == indexesToDelete[j]) { noGo = true; break; }
}
if (noGo == false) { newArray[counter] = srcArray[i]; counter++; }
}
return newArray;
}
With this method you can delete whatever indexes you supply within the indexesToDelete argument (delimited with a comma). Copy/Paste the code into your project then you can use it something like this:
JLabel[] jla = {jLabel2,jLabel3,jLabel4,jLabel5};
jla = deleteJLabelFromArray(jla, 2);
for (int i = 0; i < jla.length; i++) {
System.out.println(jla[i]);
}
In this example we are going to delete the element number 2 (remember that arrays are 0 based) and therefore jLabel4 would be removed from the Array.
Keep in mind that this would be scary stuff with really big arrays.
Hope this helps.
There is a really easy way to access the rows of a 2D array in java
for (int i = 0 ; i < integer2D.length ; i++)
getMyArray(integer2D[i]);
But, I searched in the web to find such easy way to iterate on columns of the 2D-array, like
for (int j = 0 ; j < integer2D[0].length ; j++)
getMyArray(integer2D[][i]);
or
for (int j = 0 ; j < integer2D[0].length ; j++)
getMyArray(integer2D[...][i]);
which works in some programming languages. I just found the class RealMatrix and MatrixUtils that I can convert my array2D to a real matrix and then transpose it and again convert it to an array and iterate on it. But I suppose that there exist a simpler way?
Edit: iterating on rows as I noted in the first piece of code is easy but the main question is how to iterate on columns like the second and third codes work in some other programming languages.
Edit2: As I mentioned in the last paragraph of the main question, the easiest way that I know is transposing the matrix and the iterating on its rows.
If I understand your question, you could use a for-each as an easy way to get each row like
for (int[] row : integer2D) { // <-- for each int[] in the int[][]
for (int val : row) { // <-- for each int in the int[] row
// ...
}
}
For this, you can use the BigMatrixImpl Class of the commons math library. It has a getColumnAsDoubleArray() method which will return the specified column as an array.
Delivering only one index will give you the whole row, so:
integer2D[5] // returns an int[]
will give you an integer array, which is the 6th row in your matrix.
If you supply both indexes directly you get the value of the "cell"
integer2D[5][1] // returns an int
will give you the value of the second column of the 6th row.
This is direct access to your matrix, if you want to iterate through the rows the answer from Elliott is what you are looking for.
Edit: Transposing:
int width = array.length;
int height = array[0].length;
int[][] array_new = new int[height][width];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
array_new[y][x] = array[x][y];
}
}
Hey so I'm wondering how can I make AtomicInteger a two dimensional array, From what I've found on javadocs AtomicIntegerArray is only single dimension.
int[] newArray = new int[100];
AtomicIntegerArray atomicarray = new AtomicIntegerArray(newArray);
Which creates a AtomicIntegerArray of size 100. But I would like an atomicarray with two dimensions. I've tried doing..
AtomicInteger[][] atomicArray = new AtomicInteger[100][100];
atomicArray[00][00].set(1);
But I am met with..
java.lang.NullPointerException at nz.ac.massey.threadpool.MyClass.(MyClass.java:20)
So any ideas? thanks! :)... I haven't done much work with Atomic variables before.
if this isn't possible how can I minimic a regular primitive integer two dim array into a AtomicInteger two dim array?
Just create a one-dimensional array of length m * n, you then need a function that maps a pair of integers (i, j) to one integer. i * n + j is a good start. Assuming m is the number of rows and n the number of columns.
It is a good idea to keep all of your integers inside the AtomicIntegerArray. Or you'll have to deal with concurrency your self.
You need to instantiate all of the positions in the matrix before accessing them, something like this:
atomicArray[i][j] = new AtomicInteger();
Or this, if you want to initialize each atomic integer in a certain initial value:
atomicArray[i][j] = new AtomicInteger(initialValue);
That, for all i,j positions in the matrix. Normally you'd do this using a couple of nested for loops:
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
atomicArray[i][j] = new AtomicInteger();
}
}
I'm writing a program to multiply matrices (2d arrays) as efficiently as possible, and for this i need to split my two arrays into two each and send them off to a second program to be multiplied. The issue I have is how to split a 2d array into two 2d arrays, at specific points (halfway). Does anyone have any ideas?
Lets say you have a 2d array of strings like so
String[][] array= new String[][]
{
{"a","b","c"},
{"d","e","f"},
{"h","i","j"},
{"k","l","m"}
};
Now you need a way to split these arrays at the half way point. Lets get the halfway point. Figure out how big the array is and then cut it in half. Note that you also must handle if the array is not an even length. Example, length of 3. If this is the case, we will use the Math.floor() function.
int arrayLength = array.length;
int halfWayPoint = Math.floor(arrayLength/2);
//we also need to know howmany elements are in the array
int numberOfElementsInArray = array[0].length;
Now we have all the info we need to create two 2d arrays from one. Now we must explicitly copy create and copy the data over.
//the length of the first array will be the half way point which we already have
String [][] newArrayA = new String[halfWayPoint][numberOfElementsInArray];
//this copies the data over
for(int i = 0; i < halfWayPoint; i++)
{
newArrayA[i] = array[i];
}
//now create the other array
int newArrayBLength = array.length - halfWayPoint;
String[][] newArrayB = new String[newArrayBLength][numberOfElementsInArray];
/*
* This copies the data over. Notice that the for loop starts a halfWayPoint.
* This is because this is where we left of copying in the first array.
*/
for(int i = halfWayPoint; i < array.length; i++)
{
newArrayB[i] = array[i];
}
And your done!
Now if you want to do it a little nicer, you could do it like this
int half = Math.floor(array/2);
int numberOfElementsInArray = array[0].length;
String [][] A = new String[half][numberOfElementsInArray];
String [][] B = new String[array.length - half][numberOfElementsInArray];
for(int i = 0; i < array.length; i++)
{
if(i < half)
{
A[i] = array[i];
}
else
{
B[i] = array[i];
}
}
And lastly, if you dont want to do it explicitly, you can use the built in functions. System.arraycopy() is one example. Here is a link to its api System.arraycopy()
int half = Math.floor(array/2);
int numberOfElementsInArray = array[0].length;
String [][] A = new String[half][numberOfElementsInArray];
String [][] B = new String[array.length - half][numberOfElementsInArray];
System.arraycopy(array,0,A,0,half);
System.arraycopy(array,half,B,0,array.length - half);