Access a 2d array index without coordinates in Java - java

Lets say we have a 8 x 8 2d integer array named grid and trying to select the element 0 at [5][5]
int[][] grid = new int{{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,0,1,1},
{1,1,1,1,1,1,1,1},
{1,1,1,1,1,1,1,1}};
Now the question is, is it possible to access the index of element 0 without using coordinates and just use a single number?
example: access the element 0 with the number 45, like a 1d array
I tried approaching this problem with a for loop but it is giving me out of range errors.
int x = 0;
int y = 0;
for (int i = 0;i<45;i++) {
x += 1;
if (x > grid[y].length) {
x = 0;
y += 1;
}
The code above is supposed to add x and y until it reaches the target element.

Eventually you would have to use the two indexes.
You could calculate the x and y given just a single number.
public static int getAt(int[][] matrix, int position) {
int columns = matrix[0].length; // column size, matrix has to be at least 1x1
return matrix[position / columns][position % columns];
}
public static void setAt(int[][] matrix, int position, int value) {
int columns = matrix[0].length; // column size, matrix has to be at least 1x1
matrix[position / columns][position % columns] = value;
}
Also in your example:
1) You don't need to use a for loop (and again eventually to access or modify the matrix you would have to use both indexes).
2) When y is greater or equal than the row size (8 in this case) you will receive an out of bounds exception because you only have 8 columns.
Finally the only way to access it with one index is if you transform the matrix to a 1d array.
Here you can see how:
how to convert 2d array into 1d?

Related

Finding Maximum Height and Width for 2D Array of Unknown Dimensions (Java)

In Java, I'd like to get the maximum element from both dimensions of a simple image array, ie:
int getWidth(Color[][] pixels){
//return max of dimension 1
}
int getHeight(Color[][] pixels){
//return max of dimension 2
}
I know how to do this for a 1D array in Java, I would just run a for loop with the condition of i < pixels.length. However, I'm not quite sure how .length works for a 2D array, or even if it does work. How would I approach this?
Will .length still work?
A 2D array is just simply an array, where the items in it are other arrays. Since .length works on a 1D array, it will surely work on all arrays - the amount of dimensions does not matter.
However, pixels.length gives you the length of the parent array - i.e. the array that contains all of the other arrays inside it. To get the length of the second dimension, you will have to get the length of the arrays inside it.
So, how do we get the length of the 2nd dimension?
We know that all of these arrays must be the same length, so we use the one at position 0 only because it is the only one that we can be 100% sure will always exist - an array should always have at least one element.
Then, we just get the length of that array - pixels[0].length.
If we consider 2D array they it is an array holding references to other arrays.
If we consider matrix like this:
{
{1,2,3},
{4,6},
{7,7,8,9}
}
So height for above matrix is 3 = no. of rows.
Width of matrix is 4 = Max(no. of element in each array).
int getHeight(Color[][] pixels) {
return pixels.length;
}
int getWidth(Color[][] pixels) {
int maxCount = 0;
int rows = pixels.length;
for (int i = 0; i < rows; i++) {
if (maxCount < pixels[i].length) {
maxCount = pixels[i].length;
}
}
return maxCount;
}

Shifting specific elements in a 2D Array

I am trying to shift specific elements in a two dimensional array i.e. while some elements move, others stay in a fixed position. For Example:
char arr[][] = {{'.','.','.'},{'.','u','.'},{'x','.','.'}};
will be shifted to:
arr[][] = {{'.','u','.'},{'.','.','.'},{'x','.','.'}};
I have a code sample to shift all elements in the array a certain number of places up such that it wraps around from the bottom, but can't figure out how to keep the x's in a fixed position. I read all elements into a new Array.
public static void moveUp(char arr[][], int pos){
for(int r = 0; r < 6; r ++){
for(int c = 0 ; c < 5; c++){
newArr[(r+(6-pos))%6][c] = arr[r][c];
}
}
}
This is made on the auumption that the array has 6 rows and 5 columns.
You should do a boolean if you want the 'u' to go up and the x to stay as you commented. For example, the position of 'u' should change from char[i][j] to char[i-1][j].

Centroid of matrix

Given a 2D array, I am required to come up with an algorithm which outputs the center of mass. I came up with algorithm below, however, it is producing incorrect solution when the array size is increased to 10 x 10 matrix. I wrote and ran the algorithm using java. I have not provided the codes here, but just an explanation of my algorithm as i feel that it is not right. However, I am unable to find out why.
Store into an array: Mean of each row
Store into an array: Mean of each column
The algo below is used for row and column:
Loop through the row array,
if(row = 1){
value = (mean of row 1) - (mean of row 2 + mean of row 3+ mean of row 4)
}else if(row =Length of array){
value = (mean of row 1 + mean of row 2 + mean of row 3) - (mean of row 4)}
else{
value = (mean of rows until ith row) - (ith row till end of array)
}
final value = lowest value;
I know that it is supposed to deal with mean of the rows and columns. So in my algorithm, i find out the means of rows and columns and then conduct the calculation shown above. The same algo applies to the columns.
Any and all help is appreciated. Maybe, my understanding of center of mass is incorrect. If something is not clear, then do ask. This is my own algorithm, created from my understanding of center of mass, so if its not clear, please do ask. Thank you!
Expanding on my comment, you should be able calculate the center of mass as follows:
foreach col
foreach row
massvector.x += matrix[col][row] * col
massvector.y += matrix[col][row] * row
totalmass += matrix[col][row]
massvector.x /= totalmass
massvector.y /= totalmass
The idea is based on the section "A system of particles" in https://en.wikipedia.org/wiki/Center_of_mass: treat the matrix elements as equally spaced particles laid out on a 2D plane. The position of each element is equal to its position within the matrix, i.e. column and row, while the particle mass is the value of that cell/element/matrix position.
Example-Implementation using your (now deleted) test case:
double[][] matrix = new double[][]{
{0.70,0.75,0.70,0.75,0.80},
{0.55,0.30,0.20,0.10,0.70},
{0.80,0.10,0.00,0.00,0.80},
{0.70,0.00,0.00,0.00,0.80},
{0.80,0.90,0.80,0.75,0.90}};
double cx = 0;
double cy = 0;
double m = 0;
for(int x = 0; x < matrix.length; x++ ) {
for(int y = 0; y < matrix[x].length; y++) {
cx += matrix[x][y] * x;
cy += matrix[x][y] * y;
m += matrix[x][y];
}
}
//those are center's the cell coordinates within the matrix
int cmx = (int)(cx/m);
int cmy = (int)(cy/m);
//whatever you'd need that value for (the position is more likely what you're after)
double centerOfMassValue = matrix[cmx][cmy];
The example above would return coordinates 2/2 with is the center of the 5x5 matrix.
You need to do a weighted average so for an 3x3 array,
x̄= (mass(col1)*1 + mass(col2)*2 + mass(col3)*3) / (mass(col1) + mass(col2) + mass(col3))
and similarly for y replacing columns with rows.
Once you have those two values, the pair of them will tell you the x and y coordinates of the center of mass for your array.
See example one in the following link if you need a visual example: http://www.batesville.k12.in.us/physics/APPhyNet/Dynamics/Center%20of%20Mass/2D_1.html
I assume that since you are storing the weights in a matrix, that the position in the matrix will correspond with the coordinates of the weight where the column index is x row index is y. Thus a weight at row=2,col=3 we will take to be (3,2) on the x/y coordinate system.
This code follows the solution for center of mass from a system of particles on Wikipedia:
public static Point2D.Double getCenterOfMass( double[][] matrix) {
double massTotal = 0;
double xTotal = 0;
double yTotal = 0;
for (int rowIndex = 0; rowIndex < matrix.length; rowIndex++) {
for (int colIndex = 0; colIndex < matrix[0].length; colIndex++) {
massTotal += matrix[rowIndex][colIndex];
xTotal += matrix[rowIndex][colIndex] * colIndex;
yTotal += matrix[rowIndex][colIndex] * rowIndex;
}
}
xTotal /= massTotal;
yTotal /= massTotal;
return new Point2D.Double(xTotal,yTotal);
}
Full working code here.

multiply diagonal values of a matrix in java

I want to multiply 2 diagonals of a Matrix. But i am not able to get the diagonals of matrix. like in given code two diagonals are d1=5*5*9. and d2=3*5*7 then i will use d1 and d2 values for further process.
How to do it.
Note: matrix size can be different like here its 3x3 but it can be 5x5
private static int diagonalMultiply(int [][]arr1){
int[][] arr= {
{5,2,3},
{4,5,6},
{7,8,9}
};
for ( int x = 0; x < arr.length; x++) //stepping along the x axis again.
{
for ( int y = 0; y < arr[x].length; y++) // stepping along the y axis.
{
System.out.print(arr[x][y]+" ");
}
}
return 0;
}
A diagonal of an N×N matrix has N elements. A pair of nested loops, each going from 0 to N-1, cover N2 elements. This means that you need one loop, not two.
Both diagonals can be retrieved in a single loop. Indexes of the descending diagonal are (i, i), while indexes of the ascending one are (N-i-1, i):
int N = arr.length;
for ( int i = 0; i < N ; i++) {
System.out.println(arr[i][i]+" "+arr[N-i-1][i]);
}
Demo.

Map 2D matrix to 1D array

I have two containers: a 2-dimensional NxN matrix and a 1-dimensional array which is the transposed 1D "version" of the matrix (so for a 5x5 array, I will have a 25 element array with the same values). I want to implement a query function that will take 2D coordinates as arguments but will be doing work on the equivalent 1D array.
In order to keep algorithm efficiency strictly non-quadratic I want to access only the array and not the matrix.
I've checked other questions but they all talk about converting the whole matrix to an array through nested for-loops. I don't want to do this, as that would take quadratic time to run. Instead, I want the conversion to be on-demand for a given coordinate through a query function/method. In other words for a given number of N columns/rows:
transpose(int i, int j) {
int result;
result = i * N + j;
return result;
}
This is the formula I'm using but it is not correct. For example if I want to access the element in the {5,5} position the result would be 5*5 + 5 = 30, which is greater than 25 (which would be the total number of elements for 5x5 matrix).
Thanks in advance.
If you have a 2d array and a 1d array having same elements,then the following will be true
2d[i][j]=1d[i*number_of_columns+j]
I am assuming from your post that you already have created a 1d array out of a 2d one.
Note i and j are indices and rememeber indices begin from 0
EDIT:If you are accessing an element at [5][5] (as last element)it means your array is of order 6 by 6 and not 5 by 5.So your 1d array will have 6*6=36 elements and not 25.
You can use the deepToString() method to output a 2D array to a String. This can make it easier to do things such as sort() for example.
Assuming a declared int mat2d[m][n]; with m rows and n columns, you can convert it like
int * mat1d = new int[m * n];
int k = 0;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++i)
mat1d[k++] = mat2d[i][j];
If you just want to convert between 1D and 2D coordinates, serve yourself and make functions from this:
const int width = 10;
// from 1D coordinate to 2D coordinate
int coord_1d = 25;
int coord_x = coord_1d % width;
int coord_y = coord_1d / width;
// from 2D coordinate to 1D coordinate
coord_1d = coord_x + coord_y * width;
Your question is quite confusing, you said that you don't want nested loops, here is a just-one-loop conversion
int[][] a={
{1,2,3,4,5,6},
{4,5,6,7,8,9},
{7,8,9,1,2,3},
{1,2,3,4,5,6}
};
int[]b=new int[a.length*a[0].length];
int x=0;
for(int i=0, j=0;i<a.length&&j<a[0].length;i=(j==a[0].length-1?i+1:i),j=(j+1)%a[0].length)
b[x++]=a[i][j];
System.out.println(Arrays.toString(b));
If you want the conversion to be based on coordinates, by changing i and j values in the for loop to such coordinates will allow you to convert to array only a subset of your matrix

Categories

Resources