multiply diagonal values of a matrix in java - 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.

Related

How to do dijkstra's algorithm on a grid matrix

So I have a gird that can be any given size (i.e. matrix or 2d array). Each element contains a value and simply I need to find the shortest path. However, the problem I am having is trying to represent this grid as a graph or adj matrix or what ever you are meant to do. For example this is my code:
public int shortestPath (int[][] matrix, int sr, int sc, int dr, int dc)
{
int p = matrix.length * matrix[0].length;
int[] distances = new int[p];
boolean[] visited = new boolean[p]; //I think all are set to false by default
for (int i = 0; i < p; i++)
{
distances[i] = Integer.MAX_VALUE;
}
PriorityQueue<Node> pq = new Priority<>(); // a Node holds the int row, int col and the distance from source cell. It also orders by distances, so therefore a comparable was created to change natural order.
pq.add(new Node(sr,sc,0);
distances[(sr * matrix[0].length) + sc] = 0;
visited[(sr * matrix[0].length) + sc] = true;
while(!pq.isEmpty())
{
Node n = pq.poll();
int row = n.getRow();
int col = n.getColumn();
int dist = n.getDistance();
//Now here with a normal graph I would search neighbours via a for loop and find in the adj list where an element = 1 and is not visited. This is where I am stuck
}
}
So obviously with a grid, I will need to find neighbours of left/right/up/down (not doing diagonals). Thus, I need to take into account boundaries. How can a create an Adj matrix or what is the correct way to start searching neighbours for a grid like this?
I am having bad luck with this today because most examples show in graph form to adj matrix and not from grid form to adj matrix.
There's a trick for grid graphs:
lets say {x,y} denotes difference between 2 neighbour cells
You know neighbours will be in {0,-1}, {0,1}, {1,0} or {-1,0} (assuming no diagonal moves), or those cells will be out of bounds
Save arrays of those differences:
int differenceX[] = {0,0,1,-1};
int differenceY[] = {-1,1,0,0};
Now you can use for loop for neighbours:
for(int i=0; i<4; i++)
{
int neighRow = row + differenceY[i];
int neighCol = col + differenceX[i];
if(min(neighRow, neighCol) >= 0 && neighRow < matrix.length && neighCol < matrix[0].length){
//process node
}
}

How to fill a 2D array with random non duplicate numbers in Java

I'm having a hard time figuring out how to fill my 2D array with random numbers without duplicates. I currently have it filed with random numbers within the correct range, but I just cant think of a solution to have non duplicates. How could i do this using very basic java methods? I have not yet learned anything such as arraylists, or anything like that, only the very basic methods.
Given a MxN integer array, you could fill the array with numbers from 1 to M*N using two for-loops, and then swap them using the Fisher-Yates algorithm.
EDIT:
I changed the algorithm so that it now does not create a new integer-array every time the algorithm is called. It uses one loop, and calculates m, n, i j from a random value and the iterating varaible l. Assuming the given array is not null, rectangular and at least 1x0 in size:
public static void fillRandomlyUniqe(int[][] a) {
/*
fill up the array with incrementing values
if the values should start at another value, change here
*/
int value = 1;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++)
a[i][j] = value++;
}
// swap them using Fisher-Yates algorithm
Random r = new Random();
int max = a.length * a[0].length;
for (int l = max - 1; l > 0; l--) {
//calculate a two dimensional index from random number
int index = r.nextInt(l + 1);
int m = index % a.length;
int n = index / a.length;
//calculate two dimensional index from the iterating value
int i = l % a.length;
int j = l / a.length;
int temp = a[i][j];
a[i][j] = a[m][n];
a[m][n] = temp;
}
}
If your 2D array is NxM, and you want numbers from (say) 1 to NxM randomly placed in your 2D array, the simplest is to create an array/list with the numbers from 1 to NxM, shuffle it, then fill in your 2D array sequentially from the shuffled data. You are guaranteed to not have any duplicates because the original non-shuffled data is full of unique values.
List<Integer> data = IntStream.rangeClosed(1, M * N).boxed().collect(Collectors.toList());
Collections.shuffle(data);
Iterator<Integer> iter = data.iterator();
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
array[i][j] = iter.next();
}
}
There is probably a way to do the second half with the stream API too, but it escapes me at the moment.

Transferring the contents of a one-dimensional array to a two-dimensional array

I'm trying to make an encryption program where the user enters a message and then converts the "letters into numbers".
For example the user enters a ABCD as his message. The converted number would be 1 2 3 4 and the numbers are stored into a one dimensional integer array. What I want to do is be able to put it into a 2x2 matrix with the use of two dimensional arrays.
Here's a snippet of my code:
int data[] = new int[] {10,20,30,40};
*for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for (int ctr=0; ictr<data.length(); ictr++){
a[i][j] = data[ctr];}
}
}
I know there's something wrong with the code but I am really lost.
How do I output it as the following?
10 20
30 40
(instead of just 10,20,30,40)
Here's one way of doing it. It's not the only way. Basically, for each cell in the output, you calculate the corresponding index of the initial array, then do the assignment.
int data[] = new int[] {10, 20, 30, 40, 50, 60};
int width = 3;
int height = 2;
int[][] result = new int[height][width];
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
result[i][j] = data[i * width + j];
}
}
Seems like you want to output a 2xn matrix while still having the values stored in a one-dimensional array. If that's the case then you can to this:
Assume the cardinality m of your set of values is known. Then, since you want it to be 2 rows, you calculate n=ceil(m/2), which will be the column count for your 2xn matrix. Note that if m is odd then you will only have n-1 values in your second row.
Then, for your array data (one-dimension array) which stores the values, just do
for(i=0;i<2;i++) // For each row
{
for(j=0;j<n;j++) // For each column,
// where index is baseline+j in the original one-dim array
{
System.out.print(data[i*n+j]);
}
}
But make sure you check the very last value for an odd cardinality set. Also you may want to do Integer.toString() to print the values.
Your code is close but not quite right. Specifically, your innermost loop (the one with ctr) doesn't accomplish much: it really just repeatedly sets the current a[i][j] to every value in the 1-D array, ultimately ending up with the last value in the array in every cell. Your main problem is confusion around how to work ctr into those loops.
There are two general approaches for what you are trying to do here. The general assumption I am making is that you want to pack an array of length L into an M x N 2-D array, where M x N = L exactly.
The first approach is to iterate through the 2D array, pulling the appropriate value from the 1-D array. For example (I'm using M and N for sizes below):
for (int i = 0, ctr = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j, ++ ctr) {
a[i][j] = data[ctr];
}
} // The final value of ctr would be L, since L = M * N.
Here, we use i and j as the 2-D indices, and start ctr at 0 and just increment it as we go to step through the 1-D array. This approach has another variation, which is to calculate the source index explicitly rather than using an increment, for example:
for (int i = 0; i < M; ++ i) {
for (int j = 0; j < N; ++ j) {
int ctr = i * N + j;
a[i][j] = data[ctr];
}
}
The second approach is to instead iterate through the 1-D array, and calculate the destination position in the 2-D array. Modulo and integer division can help with that:
for (int ctr = 0; ctr < L; ++ ctr) {
int i = ctr / N;
int j = ctr % N;
a[i][j] = data[ctr];
}
All of these approaches work. Some may be more convenient than others depending on your situation. Note that the two explicitly calculated approaches can be more convenient if you have to do other transformations at the same time, e.g. the last approach above would make it very easy to, say, flip your 2-D matrix horizontally.
check this solution, it works for any length of data
public class ArrayTest
{
public static void main(String[] args)
{
int data[] = new int[] {10,20,30,40,50};
int length,limit1,limit2;
length=data.length;
if(length%2==0)
{
limit1=data.length/2;
limit2=2;
}
else
{
limit1=data.length/2+1;
limit2=2;
}
int data2[][] = new int[limit1][limit2];
int ctr=0;
//stores data in 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
data2[i][j] = data[ctr];
ctr++;
}
else
{
break;
}
}
}
ctr=0;
//prints data from 2d array
for(int i=0;i<limit1;i++)
{
for(int j=0;j<limit2;j++)
{
if(ctr<length)
{
System.out.println(data2[i][j]);
ctr++;
}
else
{
break;
}
}
}
}
}

Searching a grid recursively by triangular numbers

I have a 36x25 grid of nodes that I wish to search through all triangular numbers from the corner opposite of the hypotenuse. Here's psuedocode for what I was considering, but this method only works until it hits the next corner of the grid, and I'm sure there is a much simpler way to do this recursively, I just am having difficulty figuring it out.
for(int iteration; iteration < maxDistance(49); iteration++)
{
int xAdd = iteration;
int yAdd = 0;
while(xAdd != 0)
{
checkStuff(nodeGrid[x+xAdd][y+yAdd]);
xAdd--;
yAdd++;
}
}
What I want program to do:
[0][1][2][3][4][5]
[1][2][3][4][5][6]
[2][3][4][5][6][7]
[3][4][5][6][7][8]
[4][5][6][7][8][9]
check in this order. So first check all tiles with value 0, then 1 and so on.
Note: in this case my function will only work up until the 4th set up tiles. Any further and it will reach out of bounds.
/**
* Only works for rectangular arrays
*/
public void iterateOver(Node[][] a){
int x_dim = a[0].length;
int y_dim = a.length;
for (int i = 0; i < x_dim + y_dim - 1; i++){
int x, y;
if (i < x_dim){
x = i;
y = 0;
}
else{
x = x_dim - 1;
y = i - x_dim + 1;
}
for (;x >=0 && y < y_dim; y++, x--){
doStuff(a[y][x]);
}
}
}
How it works
Picture your rectangular array:
[0][1][2][3][4][5]
[1][2][3][4][5][6]
[2][3][4][5][6][7]
[3][4][5][6][7][8]
[4][5][6][7][8][9]
There are clearly 6 columns and 5 rows (or 6 x values and 5 y values). That means that we need to do 6 + 5 - 1 iterations, or 10. Thus, the for (int i = 0; i < x_dim + y_dim - 1; i++). (i is the current iteration, measured from 0).
We start by columns. When i is less than the x dimension, x = i and y = 0 to start with. x is decremented and y is incremented until x is less than zero or y is equal to the y dimension. Then, we do a similar thing down the right hand side.

Best/Fastest way to iterate through all sub-matrices of a NxN matrix

I have a square board (NxN matrix). Each square (cell) has a certain points associated to it. My goal is to find the largest sub-matrix which has the highest summation of points. I started off with trying to find all the sub-matrices and their weights. But I am stuck on how to go about doing it.
I thought I could have a HashMap<String,Integer> which stores the initial row,column and the size of the sub matrix. The code should look something like this:
int [][] mat = new int[10][10];
void countSubMatrix()
{
for(int i = 0; i<mat.length; i++)
{
for(int j = 0; j<mat[i].length; j++)
{
storeSubMatrix(i,j);
}
}
}
void storeSubMatrix(int x, int y)
{
int size = 0;
int tempX = x;
int tempY = y;
while(tempX < board.length && tempY < board[x].length)
{
map.put(x.toString() + "," + y.toString(),size+1);
tempX++;
tempY++;
}
}
But I don't know if this is the right way to do it. Any thoughts?
Largest submatrix ,i.e, it can also be a rectangle, then this might be of help to you. Using kadane's algorithm for matrix it can be done in O(n^3).

Categories

Resources