Transpose a NxN matrix - java

I have a NxN matrix and it trying to transpose it by this code:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < mat_size; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
it doesn't work, what is the problem? thanks in advance.

It doesn't work since you're swapping the whole matrix with itself. What you need to do is exchange the upper triangle with the lower one:
for(int j = 0; j < i; ++j) {
is one way.

Going from 0 to mat_size will get you reorder the whole matrix two times, getting the original one again.
change to :
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}

You need to swap only if j > i. So the inner loop must start at i+1. For j==i (the center diagonal) no swapping is needed, too.
Your solution doesn't work because you're actually swapping twice (once with j=x and i=y and once with j=y and i=x.

For example the (2,5) is swapped for i=2,j=5 and i=5,j=2. Swap twice does nothing.
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}

This is because the elements that you swap in the lower triangle of the matrix gets swapped again when the iteration reaches the other side of the diagonal. That is the element is swapped twice which results in nothing.
Try:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}

Related

Inplace transpose of a matrix in Java

I'm trying a simple intuition to transpose a matrix in place.
I'm trying to swap elements of matrix[i][j] and matrix[j][i] but it is not working, I'm wondering what is happening behind the scene.
class Solution {
public int[][] transpose(int[][] matrix) {
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
return matrix;
}
}
Output
For matrix -> [[1,2,3],[4,5,6],[7,8,9]]
It is giving output -> [[1,2,3],[4,5,6],[7,8,9]]
but the expected output should be -> [[1,4,7],[2,5,8],[3,6,9]]
You are transposing each pair of elements twice, which puts them back how they were.
One solution would be to change for(int j = 0; in the inner loop to for(int j = i + 1;. This would make sure that each pair of elements is only transposed once.
Also be aware that this general solution only works for square matrices.
how about this way?
public int[][] transpose(int[][] matrix) {
int[][] result = new int[matrix.length][matrix[0].length];
for(int i = 0; i < matrix[0].length; i++){
for(int j = 0; j < matrix.length; j++){
result[j][i] = matrix[i][j];
System.out.println(Arrays.deepToString(result));
}
}
return result;
}

Indexing out of bounds in row reversal of matrix

public static int [][] reverseRows (int [][] matrix ) {
int i, j, k = (matrix.length - 1), l = (matrix[0].length - 1);
int [][] rr = new int[matrix.length][matrix[0].length];
for(i = 0; i < matrix.length; i++) {
for(j = 0; j < matrix[i].length; j++)
rr[k][l--] = matrix[i][j]; // <--- This line
k--;
}
printMatrix(rr);
return matrix;
}
I'm trying to reverse the rows in a matrix passed as a parameter, and I've come up with this contraption. It works for a 1x1 matrix, for obvious reasons, but not for others, and I am getting this error:
java.lang.ArrayIndexOutOfBoundsException: -1
on the line that is indicated by the comment. So my l iterator is clearly being indexed too far back, past 0 (to -1, if my eyes don't deceive me). Wouldn't l iterate the same amount of times as j? Since they are the same size, why wouldn't j be reading past the end of matrix but l is reading past rr?
your code will work fine for one iteration
for(i = 0; i < matrix.length; i++) {
for(j = 0; j < matrix[i].length; j++)
rr[k][l--] = matrix[i][j]; // <--- This line
k--;
}
You have to assign l again l = matrix[0].length-1 for next iteration
for(i = 0; i < matrix.length; i++) {
l = matrix[0].length - 1; // <--- This line
for(j = 0; j < matrix[i].length; j++)
rr[k][l--] = matrix[i][j];
k--;
}
Hope this helps.
I think you need to re-assign the value of 'l' after each j loop, in the way that your code is, variable 'l' is being decremented i*j times.
Try something like:
public static int [][] reverseRows (int [][] matrix ) {
int i, j, k = (matrix.length - 1), l = (matrix[0].length - 1);
int [][] rr = new int[matrix.length][matrix[0].length];
for(i = 0; i < matrix.length; i++) {
l = (matrix[0].length - 1);
for(j = 0; j < matrix[i].length; j++)
rr[k][l--] = matrix[i][j]; // <--- This line
k--;
}
printMatrix(rr);
return matrix;
}

Move left if there is a zero

I am trying to create a program that will take an array of integers, say {2,0,32,0,0,8} that can be of any length, and make it so all of the nonzero numbers are to the left at the lower indexes, and all the zeros are moved to the end.
For example, {2,0,32,0,0,8} becomes {2,32,8,0,0,0}.
This array can be of any length and contain any nonnegative integers.
This is what I have so far:
public static int[] moveLeft(final int[] a) {
for (int i = 0; i < a.length; i++) {
if (a[i] != 0) {
for (int j = 0; j < a.length; j++) {
if (a[j] == 0) {
a[j] = a[i];
a[i] = 0;
}
}
}
}
return a;
}
However, when I do this, it doesn't work for the first and second characters. If I have {1,2,0,1} it will return {2,1,1,0} when it should return {1,2,1,0}. Any help?
Your inner loop should stop before index i. Change this
for (int j = 0; j < a.length; j++) {
to
for (int j = 0; j < i; j++) {
And then your code works for me.

Printing ragged array column by column

Given an array of integers with rows of different lengths, is it possible to print the whole two-dimensional array but doing so column by column? I understand how to do it row by row but I am struggling with this.
int[][] a = new int[5][];
a[0] = new int[4];
a[1] = new int[2];
a[2] = new int[5];
a[3] = new int[3];
a[4] = new int[1];
int longestRowLength = a[0].length;
for(i = 1; i < a.length; i++)
{
if(a[i].length > longestRowLength)
longestRowLength = a[i].length;
}
for(i = 0; i < a.length; i++)
{
for(j = 0; j < a[i].length; j++)
{
a[i][j] = rand.nextInt(10);
System.out.print(a[i][j]);
}
System.out.println();
}
for(j = 0; j < longestRowLength; j++)
{
for(i = 0; i < a.length; i++)
{
if(a[i].length < longestRowLength)
continue;
System.out.print(a[i][j]);
}
}
}
I have done this but the issue is with how to recognize we are going out of bounds with one of the arrays. My if(a[i].length < longestRowLength doesn't work as it will not even print any numbers if its length is not the longest ones. How can I achieve this?
EDIT:
Ok I have changed that line to:
if(longestRowLength - a[i].length > 0 && (j+1) > a[i].length)
continue;
System.out.print(a[i][j]);
Now it works but it prints the columns as rows. Is there anyway to make it print column by column but to make it print just like it would with rows? (P.S. yeah the first condition of the if statement is unecessary).
Replace your last loop with:
for(j = 0; j < longestRowLength; j++)
{
for(i = 0; i < a.length; i++)
{
if(a[i].length <= j)
continue;
System.out.print(a[i][j]);
}
System.out.println();
}
Prints the columns one by one.
Instead of:
if(a[i].length <= j)
continue;
you can do:
if(a[i].length <= j) {
System.out.print(' ');
continue;
}
to leave a space for arrays which are too short. This way you print the transposed “jagged” matrix.

Java loop over half of array

I would like to loop over half of an array in Java; this is because the matrix will be completely symmetric. If I loop throw i columns and j rows, every time I do an operation of matrix[i][j] I will do the exact same operation to matrix[j][i]. I should be able to save time by not looping over half of the matrix. Any ideas on the easiest way to do this?
If you're trying to get a triangle:
for(int i=0; i<array.length; i++){
for(int j=0; j<=i; j++){
..do stuff...
}
}
for (i = 0;i < size; ++i) {
for (j = 0; j < i; ++j) {
result = do_operation(i,j);
matrix[i][j] = result;
matrix[j][i] = result ;
}
}
So you invoke the operation method do_operation only once for each pair.
for(int i = 0; i<array.length; i++){
for(int j = 0; j < array[i].length - i; j++){
// operation here
}
}
Maybe I'm missing something here, but let's say you have two arrays representing your rows and columns respectively, and assuming that it's symmetric (as you say):
int dimension = rows.Length;
for(int i=0; i<dimension; i++)
{
int j = (dimension-1) - i; //need dimension-1 to avoid an off-by-one error
DoSomething(matrix[i][j]);
DoSomehting(matrix[j][i]);
}
This solution has the runtime complexity benefit of only iterating over one loop as opposed to two.

Categories