Transposing a matrix from a 2D array - java

I'm self teaching myself some java and I'm stuck on creating a 2D array that initializes it with random values and then creates the transpose of the array.
An example output is:
$ java Test1 22 333 44 555 6
Enter the number of rows (1-10): 0
ERROR: number not in specified range (1-10) !
and so on until you enter the correct number of rows and columns.
Original matrix
1 22
333 44
555 6
Transposed matrix
1 333 555`
22 44 6`
^ Should be the final output. Some help with the code would appreciated!
I would like to code to generate error messages if the number of rows or columns is outside the specified range. And for if to read the matrix elements from the command line and not generate them randomly.
import java.util.Scanner;
public class Test1 {
/** Main method */
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter the number of rows (1-10): ");
int rows = input.nextInt();
System.out.print("Enter the number of columns (1-10): ");
int cols = input.nextInt();
// Create originalMatrix as rectangular two dimensional array
int[][] originalMatrix = new int[rows][cols];
// Assign random values to originalMatrix
for (int row = 0; row < originalMatrix.length; row++)
for (int col = 0; col < originalMatrix[row].length; col++) {
originalMatrix[row][col] = (int) (Math.random() * 1000);
}
// Print original matrix
System.out.println("\nOriginal matrix:");
printMatrix(originalMatrix);
// Transpose matrix
int[][] resultMatrix = transposeMatrix(originalMatrix);
// Print transposed matrix
System.out.println("\nTransposed matrix:");
printMatrix(resultMatrix);
}
/** The method for printing the contents of a matrix */
public static void printMatrix(int[][] matrix) {
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
System.out.print(matrix[row][col] + " ");
}
System.out.println();
}
}
/** The method for transposing a matrix */
public static int[][] transposeMatrix(int[][] matrix) {
// Code goes here...
}
}

This is a simple method that return an int[][] of the transposed matrix...
public static int[][] transposeMatrix(int[][] matrix){
int m = matrix.length;
int n = matrix[0].length;
int[][] transposedMatrix = new int[n][m];
for(int x = 0; x < n; x++) {
for(int y = 0; y < m; y++) {
transposedMatrix[x][y] = matrix[y][x];
}
}
return transposedMatrix;
}
Than to print a 2D matrix you can use a method like this:
public static String matrixToString(int[][] a){
int m = a.length;
int n = a[0].length;
String tmp = "";
for(int y = 0; y<m; y++){
for(int x = 0; x<n; x++){
tmp = tmp + a[y][x] + " ";
}
tmp = tmp + "\n";
}
return tmp;
}

The answer provided above is not efficient in terms of memory. It is using another array - transposedMatrix apart from array supplied as argument. This will lead to consume double memory. We can do this in-place as follows:
public void transposeMatrix(int[][] a)
{
int temp;
for(int i=0 ; i<(a.length/2 + 1); i++)
{
for(int j=i ; j<(a[0].length) ; j++)
{
temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
displayMatrix(a);
}
public void displayMatrix(int[][] a){
for(int i=0 ; i<a.length ; i++)
{
for(int j=0 ; j<a[0].length ; j++)
{
System.out.print(a[i][j] + " ");
}
System.out.println();
}
}

You can use the below class it has most of the methods you want.
/**
* Class representing square matrix of given size.
* It has methods to rotate by 90, 180 and 270
* And also to transpose and flip on either axis.
*
* I have used both space efficient methods in transpose and flip
* And simple but more space usage for rotation.
*
* This is using builder pattern hence, you can keep on applying
* methods say rotate90().rotate90() to get 180 turn.
*
*/
public class Matrix {
private int[][] matrix;
final int size;
public Matrix(final int size) {
this.size = size;
matrix = new int[size][size];
for (int i=0;i<size;i++)
for (int j=0;j<size;j++)
matrix[i][j] = i*size + j;
}
public Matrix rotate90() {
int[][] temp = new int[size][size];
for (int i=0;i<size;i++)
for (int j=0;j<size;j++)
temp[i][j] = matrix[size-1-j][i];
matrix = temp;
return this;
}
public Matrix rotate180() {
int[][] temp = new int[size][size];
for (int i=0;i<size;i++)
for (int j=0;j<size;j++)
temp[i][j] = matrix[size-1-i][size-1-j];
matrix = temp;
return this;
}
public Matrix rotate270() {
int[][] temp = new int[size][size];
for (int i=0;i<size;i++)
for (int j=0;j<size;j++)
temp[i][j] = matrix[j][size-1-i];
matrix = temp;
return this;
}
public Matrix transpose() {
for (int i=0; i<size-1; i++) {
for (int j=i+1; j<size; j++) {
int tmp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = tmp;
}
}
return this;
}
public Matrix flipVertical() {
for (int i=0; i<size; i++) {
for (int j=0; j<size/2; j++) {
int tmp = matrix[i][size-1-j];
matrix[i][size-1-j] = matrix[i][j];
matrix[i][j] = tmp;
}
}
return this;
}
public Matrix flipHorizontal() {
for (int i=0; i<size/2; i++) {
for (int j=0; j<size; j++) {
int tmp = matrix[size-1-i][j];
matrix[size-1-i][j] = matrix[i][j];
matrix[i][j] = tmp;
}
}
return this;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i=0;i<size;i++) {
for (int j=0;j<size;j++) {
sb.append("|");
sb.append(matrix[i][j]);
if (size > 3) {
sb.append("\t");
}
}
sb.append("|\n");
}
return sb.toString();
}
public static void main(String... args) {
Matrix m = new Matrix(3);
System.out.println(m);
//transpose and flipHorizontal is 270 turn (-90)
System.out.println(m.transpose());
System.out.println(m.flipHorizontal());
//rotate 90 further to bring it back to original position
System.out.println(m.rotate90());
//transpose and flip Vertical is 90 degree turn
System.out.println(m.transpose().flipVertical());
}
}
Output:
|0|1|2|
|3|4|5|
|6|7|8|
|0|3|6|
|1|4|7|
|2|5|8|
|2|5|8|
|1|4|7|
|0|3|6|
|0|1|2|
|3|4|5|
|6|7|8|
|6|3|0|
|7|4|1|
|8|5|2|

For a square matrix, instead of iterating through the entire array, you just iterate through the diagonally half of the 2D array and swap the values with the corresponding indices.
public void transposeMatrix(int[][] a) {
for(int i=0 ; i<n; i++) {
for(int j=0 ; j<i ; j++) {
int temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
}

Another Kotlin solution for n x m matrix
fun transpose(matrix: Array<Array<Double>>): Array<Array<Double>> {
return matrix[0].mapIndexed { col, _ ->
matrix.mapIndexed { row, _ ->
matrix[row][col]
}.toTypedArray()
}.toTypedArray()
}
fun printMatrix(matrix: Array<Array<Double>>) {
println(matrix.joinToString("\n") { it.contentToString() })
}
fun main() {
val matrix = arrayOf(
arrayOf( 1.0, 2.0, 3.0),
arrayOf( 4.0, 5.0, 6.0),
arrayOf( 7.0, 8.0, 9.0),
arrayOf( 1.0, 2.0, 3.0),
)
println("matrix:")
printMatrix(matrix)
println("transpose(matrix):")
printMatrix(transpose(matrix))
}
Output
matrix:
[1.0, 2.0, 3.0]
[4.0, 5.0, 6.0]
[7.0, 8.0, 9.0]
[1.0, 2.0, 3.0]
transpose(matrix):
[1.0, 4.0, 7.0, 1.0]
[2.0, 5.0, 8.0, 2.0]
[3.0, 6.0, 9.0, 3.0]
Try it in the Kotlin Playground

Here is Kotlin Solution!
fun displayMatrix(matrix: Array<IntArray>) {
for(row in matrix) {
for(column in row) {
print("$column ")
}
println()
}
}
fun main() {
//Create Array
val matrixA = arrayOf(intArrayOf(2, 3, 4), intArrayOf(5, 6, 4), intArrayOf(1, 6, 7), intArrayOf(0, 2, 8))
println("Dimension on X: ${matrixA[0].size}")
println("Dimension on Y: ${matrixA.size}")
displayMatrix(matrixA)
println()
val transposeMatrix = Array(matrixA[0].size) { IntArray(matrixA.size) }
for(i in 0..matrixA.size - 1) {
for(j in 0..matrixA[0].size - 1) {
transposeMatrix[j][i] = matrixA[i][j]
}
}
displayMatrix(transposeMatrix)
}

Related

Merging two 2D arrays (M + N)

I am a first year programming trying to solve this challenge that was given to us students at uni.
Question image
There's a typo at where it says (N + K) whereas in fact it's actually (M+K) columns.
My attempt for this question goes as follows
public static int[][] mergeArrays(int[][] arrayA, int[][] arrayB){
int rows = 3;
int columns = arrayA[0].length + arrayB[0].length;
int[][] mergedArray = new int[rows][columns];
int k = 0;
for (int i = 0; i < rows; i++)
{
for ( int j = 0 ; j < columns; j++)
{
try
{
mergedArray[i][j] = arrayA[i][j];
}
catch (ArrayIndexOutOfBoundsException e)
{
mergedArray[i][j] = arrayB[i][k];
k += 1;
}
}
}
return mergedArray;
}
public static void main(String [] args)
{
int [][] a1 = { {1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3} };
int [][] a2 = { {1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2} };
int[][] m = mergeArrays(a1,a2);
for (int[] x : m)
{
for (int y : x)
{
System.out.print(y + " ");
}
System.out.println();
}
}
The program doesn't work for some reason. I don't know what's wrong with my approach here. Would really appreciate if someone helps me out.
Without using any libraries, in a manual way, here is my working answer.
I didn't use any of them, since we were not allowed, when I was a student.
public class Main {
private static int[][] mergeArrays(int[][] a1, int[][] a2) {
// Count rows and cols length.
int rows = a1.length;
int cols_a1 = a1[0].length;
int cols_a2 = a2[0].length;
// Total number of cols
int cols = cols_a2 + cols_a1;
int [][] merged = new int[rows][cols];
for (int i = 0; i < rows ; ++i) {
for (int j = 0; j < cols_a1; ++j) {
merged[i][j] = a1[i][j];
}
// To not overwrite values,
// the trick is to add an offset, while assigning,
// which is the amount of elements (cols_a1) used by the previous loop.
// Basically, we are shifting the k-index by this constant,
// as to not overwrite the values assigned from the previous
// inner loop.
for (int k = 0; k < cols_a2; ++k) {
merged[i][cols_a1 + k] = a2[i][k];
}
}
// Return the merged array
return merged;
}
// I refactored your good printing code into a method, for readability.
private static void print2darray(int[][] array2d) {
for (int[] x : array2d) {
for (int y : x) {
System.out.print(y + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
int [][] a1 = {{1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3}};
int [][] a2 = {{1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2}};
int [][] merged = mergeArrays(a1, a2);
print2darray(merged);
}
}
The result is the same, as expected, from your question image:
1 2 3 3 3 1 9 7 2 3
3 2 1 6 3 0 7 8 3 2
4 5 6 1 3 3 8 9 7 2
Since you're a student I think to better if we give a hint, but since the solution is already there you can check this one as well:
public static int[] merge(int[] first,int[] second) {
return ArrayUtils.addAll(first, second);
}
public static void main(String[] args) {
int [][] a1 = { {1,2,3,3,3} , {3,2,1,6,3} , {4,5,6,1,3}};
int [][] a2 = { {1,9,7,2,3} , {0,7,8,3,2} , {3,8,9,7,2}};
int [][] a3 = new int[a1.length][];
for (int i = 0; i < a1.length; i++) {
a3[i] = merge(a1[i],a2[i]);
}
for (int[] ints : a3) {
StringJoiner joiner = new StringJoiner(",","[","]");
for (int i1 : ints) {
joiner.add(i1+"");
}
System.out.println(joiner.toString());
}
}
You are not merging it properly. Your logic is that if arrayA column index is out of bounds, you are adding from arrayB's columns. But what if that is also out of bounds, as in your case. Since you are always incrementing its index k. You could simply iterate over 2 arrays separately and merge into resulting array.
public static int[][] mergeArrays(int[][] arrayA, int[][] arrayB) {
int rows = 3;
int columns = arrayA[0].length + arrayB[0].length;
int[][] mergedArray = new int[rows][columns];
int k = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < arrayA[0].length; j++) {
mergedArray[i][k++] = arrayA[i][j];
}
for (int j = 0; j < arrayB[0].length; j++) {
mergedArray[i][k++] = arrayB[i][j];
}
k=0;
}
return mergedArray;
}

Remove rows and columns from the matrix

"Find the maximum element (s) in the matrix and remove from the matrix all the rows and columns containing it".
I made the methods. In one, I find the largest number in the matrix. And in the second, I delete from the matrix the row and column that contains the largest number. But it works correctly only if the largest number is the only one. How to make, that deleted all lines and all columns in which the greatest number contains?
private void deleteRowCol() {
int[][] matrix = getMatrix();
int max = matrix[0][0];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (max < matrix[i][j]) {
max = matrix[i][j];
}
}
}
int[] m = findIdMax(matrix, max);
int[][] outMatrix = new int[matrix.length - 1][matrix[0].length - 1];
int r = 0;
for (int i = 0; i < outMatrix.length; i++) {
if (i > m[0] - 1) {
r = 1;
}
int c = 0;
for (int j = 0; j < outMatrix[0].length; j++) {
if (j > m[1] - 1) {
c = 1;
}
outMatrix[i][j] = matrix[i + r][j + c];
}
}
System.out.println(" ");
outputMatrix(outMatrix);
}
private int[] findIdMax(int[][] matrix, int max) {
int[] id = {0, 0};
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if (max == matrix[i][j]) {
id[0] = i;
id[1] = j;
}
}
}
return id;
}
expected output:
with this matrix
4 2 0 -3
4 -1 4 1
0 2 -4 3
-4 -1 -4 -2
should bring
-2 3
-1 -2
I haven't been able to find a fix for your current code. One issue is that you always assume 1 row and 1 column are deleted with int[][] outMatrix = new int[matrix.length - 1][matrix[0].length - 1];. If I put a loop around your code it would fail if the max is for example at positions 1,2 and 1,4 in the matrix (which should remove only 1 row, but 2 columns).
So perhaps someone else could take a closer look at your implementation and see a straight-forward fix without changing too much. Instead, I've thought about the use case from scratch and tried to complete the task myself. I ended up with the following code:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
class Main{
private Set<Integer> rowsToDelete,
columnsToDelete;
public static void main(String[] a){
Main program = new Main();
int[][] matrix = program.getMatrix();
System.out.println("Before:");
program.prettyPrintMatrix(matrix);
System.out.println();
int[][] modifiedMatrix = program.deleteRowCol(matrix);
System.out.println("After:");
program.prettyPrintMatrix(modifiedMatrix);
}
private int[][] getMatrix(){
// Test:
return new int[][]{
{ 4, 2, 0,-3},
{ 4,-1, 4, 1},
{ 0, 2,-4, 3},
{-4,-1,-4,-2}
};
}
private int[][] deleteRowCol(int[][] matrix) {
int max = findMax(matrix);
determineCoordinatesMax(matrix, max);
// Some debug prints:
System.out.println("Maximum: "+max);
System.out.println("Rows to delete: "+rowsToDelete);
System.out.println("Columns to delete: "+columnsToDelete);
System.out.println();
int[][] modifiedMatrix = deleteRows(matrix);
modifiedMatrix = deleteColumns(modifiedMatrix);
return modifiedMatrix;
}
private int findMax(int[][] matrix){
int max = matrix[0][0];
for(int[] row : matrix){
for(int value : row){
if(value > max){
max = value;
}
}
}
return max;
}
private void determineCoordinatesMax(int[][] matrix, int max) {
rowsToDelete = new HashSet<>();
columnsToDelete = new HashSet<>();
for(int r=0; r<matrix.length; r++){
for(int c=0; c<matrix[r].length; c++){
if(matrix[r][c] == max){
rowsToDelete.add(r);
columnsToDelete.add(c);
}
}
}
}
private int[][] deleteRows(int[][] matrix){
int rowsToLeave = matrix.length - rowsToDelete.size();
int[][] modifiedMatrix = new int[rowsToLeave][];
int i = 0;
for(int r=0; r<matrix.length; r++){
if(!rowsToDelete.contains(r)){
modifiedMatrix[i] = matrix[r];
i++;
}
}
return modifiedMatrix;
}
private int[][] deleteColumns(int[][] matrix){
int columnsAlreadyDeleted = 0;
for(int columnToDelete : columnsToDelete){
// Delete the columns one by one:
int[][] modifiedMatrix = new int[matrix.length][matrix[0].length - 1];
for(int r=0; r<matrix.length; r++){
int i=0;
for(int c=0; c<matrix[r].length; c++){
if(c != columnToDelete - columnsAlreadyDeleted){
modifiedMatrix[r][i] = matrix[r][c];
i++;
}
}
}
columnsAlreadyDeleted++;
matrix = modifiedMatrix;
}
return matrix;
}
private void prettyPrintMatrix(int[][] matrix){
for(int[] row : matrix){
System.out.println(Arrays.toString(row));
}
}
}
The deletion of the columns could use some tweaking, since I now have three nested loops (loop over the columns to delete; inner loop over the matrix-rows; inner loop over the matrix-columns). But it works, and removes the rows and columns of the int[][] as expected.
You can see it in action here: Try it online.

Java: Create a duplicate of an array without making it a reference

I have written a series of matrix operations where I take a 2 dimensional float array, treat it as a matrix, and perform matrix operations on it to acquire an inverse. My problem has been that although the array I am using with the class methods isn't part of the class, every time I run the method with the array as the parameter, the array itself also becomes modified.
First I will describe how I got the inverse of my matrix and then I will show the output.
The steps to taking the inverse of a matrix are as follows:
Get the cofactor matrix (i.e. create a matrix of matrix minors of the original matrix and then negate every other entry. If C = Cofactor Matrix, M = Matrix of Minors, i is the current row, and j is the current column, then C[ i ][ j ] = M[ i ][ j ]*( -1 )^( i + j )
Convert the cofactor matrix to the adjugate (also known as adjoint) matrix by transposing (replacing row, column entry by its analogous column, row entry and vice versa) the cofactor matrix. If C = Cofactor Matrix, A = Adjugate Matrix, i is the current row, and j is the current column, then A[ i ][ j ] = C[ j ][ i ]
Finally, take one over determinant of the original matrix and multiply the adjugate matrix by that value. If I = Inverse Matrix, A = Adjugate Matrix and D = Determinant, then I = (1/D)*A
In order to test if you have truly acquired the Matrix Inverse of a Matrix, one can multiply the original matrix by its inverse to get the identity matrix.
If I = Inverse, O = Original Matrix, and id = Identity Matrix then O*I = id
Now I will present the code where I implement these operations. For the sake of conciseness, I will not describe how to get the Matrix of Minors or the Determinant, but the problem I have been encountering will become apparent anyways.
public class MatrixOperations {
//Note: this method works fine. There are no problems.
public float determinant(float [][] a)
{
float [][] temp_mat;
float res = 0;
//assuming a square matrix
/*If it's a 2X2, then use the formula for a determinant of
2X2 matrices.*/
if(a.length == 2)
{
return a[0][0]*a[1][1]-a[0][1]*a[1][0];
}
/*Otherwise do the determinant formula recursively until your
determinant is made up of 2X2 matrix determinants and scalar products*/
else
{
temp_mat = new float[a.length-1][a.length-1];
int placej = 0;
int placei = 0;
for(int k = 0; k<a.length;k++)
{
for(int j = 0; j<a.length; j++)
{
for(int i = 1; i < a.length; i++)
{
placei = i-1;
if(j != k)
{
if(j < k)
{
temp_mat[placei][j] = a[i][j];
}
else if(j > k)
{
if (i == 1){
placej = j-1;
}
temp_mat[placei][placej] = a[i][j];
}
}
}
}
res+=a[0][k]*determinant(temp_mat)*(int)Math.pow(-1, k);
}
return res;
}
}
//Note: this method also works fine
//Scalar product method
public float[][] mul(float[][] m, float r)
{
float[][] res = new float[m.length][m.length];
for(int i = 0; i < m.length; i++)
{
for(int j = 0; j < m.length; j++)
{
res[i][j]= m[i][j]*r;
}
}
return res;
}
//Note: This method also works fine
public float[][] mul(float[][] m,float[][] n)
{
float[][] res = new float[m.length][m.length];
for(int i = 0; i < m.length; i++)
{
for(int j = 0; j < m.length; j++)
{
for(int k = 0; k < m.length; k++)
{
res[i][j] += m[i][k]*m[k][i];
}
}
}
return res;
}
//The method for creating a matrix of minors
//Here I start having problems
public float[][] minor(float [][] m)
{
float [][] minor_mat = new float [m.length][m.length];
//If the matrix is greater than a 2X2, use this to generate a matrix of minors
if(m.length > 2)
{
float [][] current_minor = new float [m.length-1][m.length-1];
int placei = 0;
int placej = 0;
for(int i = 0; i < m.length; i++)
{
for(int j = 0; j < m.length; j++)
{
for(int k = 0; k < m.length; k++)
{
for(int l = 0; l < m.length; l++)
{
if(i != k && j != l)
{
if(k<i)
placei = k;
else if(k>i)
placei = k-1;
if(l<j)
placej = l;
else if(l>j)
placej = l-1;
current_minor[placei][placej] = m[k][l];
}
}
}
minor_mat[i][j] = this.determinant(current_minor);
}
}
}
//otherwise use the definition for 2X2 matrix of minors
else
{
//even though minor_mat is using m.clone() rather than m, when I return the result, m has still been modified for some reason.
minor_mat = m.clone()
float temp;
temp = minor_mat[0][0];
minor_mat[0][0] = minor_mat[1][1];
minor_mat[1][1] = temp;
temp = minor_mat[0][1];
minor_mat[0][1] = minor_mat[1][0];
minor_mat[1][0] = temp;
}
return minor_mat;
}
//the same problem occurs here as it did in the minor method
//m appears to get modified even though I only use m.clone()
public float[][] cofactor(float [][] m)
{
float[][] res = m.clone();
res = this.minor(res)
for(int i = 0; i < m.length; i++)
{
for(int j = 0; j < m.length; j++)
{
res[i][j] = res[i][j]*(int)Math.pow(-1, i + j);
}
}
return res;
}
//The following transpose, adjugate, and inverse methods have the same problem
public float[][] transpose(float[][] m)
{
float[][] res = new float[m.length][m.length];
float temp = 0;
for(int i = 0; i < m.length; i++)
{
for(int j = 0; j < m.length; j++)
{
temp = m[i][j];
res[i][j] = m[j][i];
res[j][i] = temp;
}
}
return res;
}
public float[][] adjugate(float[][] m)
{
float[][] res = this.transpose(this.cofactor(m));
return res;
}
public float[][] inverse(float[][] m)
{
float[][] res = this.mul(this.adjugate(m), (1/this.determinant(m)));
return res;
}
//print out the matrix in square form
public void matrixprint(float [][] m)
{
for(int i = 0; i < m.length; i++)
{
System.out.println("");
for(int j = 0; j < m[i].length; j++){
System.out.print(m[i][j] + " ");
}
}
System.out.println("\n");
}
}
Now the main class and the main method that creates an instance of the MatrixOperations class and uses its methods on a 2X2 matrix.
public class Main {
public static void main(String[] args) {
MatrixOperations mo = new MatrixOperations();
//Create a 2X2 matrix called "matrix" and set its elements
//Then perform each step on "matrix" and finally test if you have acquired the correct inverse
float [][] matrix = new float[2][2];
matrix[0][0] = 2;
matrix [0][1] = 5;
matrix [1][0] = 4;
matrix [1][1] = 3;
System.out.println("Matrix = ");
mo.matrixprint(matrix);
System.out.println("Minor = ");
mo.matrixprint(mo.minor(matrix));
System.out.println("Matrix = ");
mo.matrixprint(matrix);
System.out.println("Cofactor = ");
mo.matrixprint(mo.cofactor(matrix));
System.out.println("Matrix = ");
mo.matrixprint(matrix);
System.out.println("Adjugate = ");
mo.matrixprint(mo.adjugate(matrix));
System.out.println("Matrix = ");
mo.matrixprint(matrix);
System.out.println("Determinant = ");
System.out.println(mo.determinant(matrix));
System.out.println("Matrix = ");
mo.matrixprint(matrix);
System.out.println("Inverse = ");
mo.matrixprint(mo.inverse(matrix));
System.out.println("Matrix = ");
mo.matrixprint(matrix);
System.out.println("Identity = ");
mo.matrixprint(mo.mul(mo.inverse(matrix), matrix));
}
}
Now you will see that when I show the output, every time I use a method on "matrix", and reprint "matrix", "matrix" itself has been modified even though my methods only use a copy of "matrix" and not "matrix" itself.
Output:
Matrix =
2.0 5.0
4.0 3.0
Minor =
3.0 4.0
5.0 2.0
Matrix =
3.0 4.0
5.0 2.0
Cofactor =
3.0 -4.0
-5.0 2.0
Matrix =
3.0 -4.0
-5.0 2.0
Adjugate =
3.0 5.0
4.0 2.0
Matrix =
3.0 4.0
5.0 2.0
Determinant =
-14.0
Matrix =
3.0 4.0
5.0 2.0
Inverse =
-0.21428573 0.35714287
0.2857143 -0.14285715
Matrix =
3.0 -4.0
-5.0 2.0
Identity =
0.1479592 0.1479592
0.12244898 0.12244898
Any help/explanation as to why this happens would be appreciated.
This line does a shallow clone;
float[][] res = m.clone();
This copies the res which is array fo references to arrays. but not any of the arrays res points to. Most likely what you wanted is
float[][] res = new float[m.length][];
for (int i = 0; i < m.length; i++)
res[i] = m[i].clone();
It's because you are passing reference of matrix object in the methods of MatrixOperations class. It's not a copy of matrix object.
From Java doc:
Reference data type parameters, such as objects, are also passed into
methods by value. This means that when the method returns, the
passed-in reference still references the same object as before.
A two-dimensional array is just an array of arrays.
clone() on an array just does a shallow clone.
So you have a new cloned outer array, but it references the same entries (the inner arrays).
After cloning the outer array, iterate over the outer array and clone all inner arrays to get a deep clone.

2D Array Methods & Demo

I have an assignment to design and implement methods to process 2D Arrays.
It needs to have an implementation class (Array2DMethods) that has the following static methods:
readInputs() to read the number of rows and columns fro the user then reads a corresponding entry to that size. Ex: if a user enters 3 for # of rows and 3 for # of columns it'll declare an array of 10 and reads 9 entries.
max(int [][] anArray) it returns the max value in the 2D parameter array anArray
rowSum(int[][] anArray) it returns the sum of the elements in row x of anArray
columnSum(int[][] anArray) it returns the sum of the elements in column x of anArray **careful w/ rows of different lengths
isSquare(int[][] anArray) checks if the array is square (meaning every row has the same length as anArray itself)
displayOutputs(int[][] anArray) displays the 2 Dim Array elements
It also needs a testing class (Arrays2DDemo) that tests the methods.
I've commented the parts I'm having problems with. I'm not sure how to test the methods besides the readInputs method and also not sure how to format the part where you ask the user to enter a number for each row.
Here's my code so far:
import java.util.Scanner;
class Array2DMethods {
public static int [][] readInputs(){
Scanner keyboard = new Scanner(System.in);
System.out.print(" How many rows? ");
int rows = keyboard.nextInt();
System.out.print(" How many columns? ");
int columns = keyboard.nextInt();
int [][] ret = new int[rows][columns];
for (int i = 0; i<ret.length; i++) {
for (int j = 0; j < ret[i].length; j++) {
System.out.print("please enter an integer: "); //Need to format like Enter [0][0]: ... Enter [0][1]: ...etc.
ret[i][j] = keyboard.nextInt();
}
}
return ret;
}
public static int max(int [][] anArray) {
int ret = Integer.MIN_VALUE;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
if (anArray[i][j] > ret) {
ret = anArray[i][j];
}
}
}
return ret;
}
public static void rowSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i<anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static void columnSum(int[][]anArray) {
int ret = 0;
for (int i = 0; i < anArray.length; i++) {
for (int j = 0; j < anArray[i].length; j++) {
ret = ret + anArray[i][j];
}
}
}
public static boolean isSquare(int[][]anArray) {
for (int i = 0, l = anArray.length; i < l; i++) {
if (anArray[i].length != l) {
return false;
}
}
return true;
}
public static void displayOutputs(int[][]anArray) {
System.out.println("Here is your 2Dim Array:");
for(int i=0; i<anArray.length; i++) {
for(int j=0; j<anArray[i].length; j++) {
System.out.print(anArray[i][j]);
System.out.print(", ");
}
System.out.println();
}
}
}
Class Arrays2DDemo:
public class Arrays2DDemo {
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int [][] anArray = Array2DMethods.readInputs();
Array2DMethods.max(anArray);
Array2DMethods.rowSum(anArray);
//need to print out and format like this: Ex Sum of row 1 = 60 ...etc
Array2DMethods.columnSum(anArray);
//need to print out and format like this: Ex Sum of column 1 = 60 ...etc.
Array2DMethods.isSquare(anArray);
//need to print out is this a square array? true
Array2DMethods.displayOutputs(anArray);
//need it to be formatted like [10, 20, 30] etc
}
}
Assuming you want anArray to be the array you read in during your inputting, you should name that variable, as such...
public static void main(String[] args){
System.out.println("Let's create a 2Dim Array!");
int[][] anArray = Array2DMethods.readInputs();
System.out.println("max " + Array2DMethods.max(anArray));
Array2DMethods.rowSum(anArray);
Array2DMethods.columnSum(anArray);
System.out.println("Square " + Array2DMethods.isSquare(anArray));
Array2DMethods.displayOutputs(anArray);
}
Say you have a function f which takes a single input x. The problem is you're asking the computer to evaluate f(x) without ever telling it what x is. If you give x a value, however, such as x = 3, then asking f(x) becomes legal, because it becomes f(3), which can be evaluated.

Java Diagonal Matrix

I have been wondering how to diagonally wrap, from bottom left, a String into a matrix.
For example:
String str = "123456789";
//Output matrix:
// 479
// 258
// 136
//Or if str = "123456789123456";
//Output would be:
// 2
// 73
// 484
// 2595
// 13616
Here is what I have so far:
int index = 0;
for(int i = 0; i < matrix.length; i++)
{
for(int k = matrix.length - 1; k > -1; k--)
{
if(index == word.length())
break;
matrix[k][i] = "" + str.charAt(index);
index++;
}
}
This is reasonably efficient implementation which I believe is relatively easy to understand.
This code loops over successive diagonals, and when the current position is inside the matrix, it assigns the next character from the string.
In the below chart, the question mark positions are on the diagonal but they're not inside the matrix. No character is taken from the input string for these question mark positions.
Diagonal Matrix
4 ?
3 ??
2 479
1 258?
0 136??
The loop goes through rows in ascending order, but the assignment to each row is done in reverse because your matrix is upside down when viewed from the normal Java way of indexing arrays: matrix[size - row - 1] instead of matrix[row].
There is no need for special treatment of below, at and above the diagonal this way.
public static void main(String[] args) throws Exception {
String str = "123456789";
int size = 3;
int[][] matrix = new int[size][size];
{
int index = 0;
for (int diagonal = 0; diagonal < size * 2 - 1; diagonal++) {
int row = diagonal;
int column = 0;
while (row >= 0) {
if (row < size && column < size) {
matrix[size - row - 1][column] = Character.getNumericValue(str.charAt(index++));
}
row--;
column++;
}
}
}
}
It also works for larger sized matrices (4x4, 5x5 etc.) but you can only encode values up to 9 in your string - if you want higher values, it's better to encode them in a comma-separated string and split the string into an array of strings.
Not making any claims about efficiency here, but it should work so long as your string fits into a square matrix:
static char[][] toDiag(String s)
{
int sideLen = (int) Math.sqrt(s.length()); // assume string fits into
// square matrix
char[][] m = new char[sideLen][sideLen];
int index = 0;
//fill lower-left section of array
for (int i = m[0].length - 1; i >= 0; i--)
{
for (int k = 0; k <= m[0].length-1-i; k++)
{
m[i+k][k] = s.charAt(index++);
}
}
//fill upper-right section of array
for (int i = sideLen%2==1?sideLen/2:sideLen/2 -1; i <= m[0].length; i++)
{
for (int k = 0; k <= m[0].length-1-i; k++)
{
m[k][i+k] = s.charAt(index++);
}
}
return m;
}
public static void main(String[] args)
{
String inString = "123456789";
int N = (int) Math.sqrt((double) inString.length());
int out[][] = new int[N][N];
int index=0;
//fills elements below the diagonal
for(int i=0;i<N-1;i++)
for(int j=0;j<=i;j++)
out[N-1-i+j][j] = Character.getNumericValue(inString.charAt(index++));
//fills the diagonal
for(int i=0;i<N;i++)
out[i][i] = Character.getNumericValue(inString.charAt(index++));
//fills elements above the diagonal
for(int i=N-2;i>=0;i--)
for(int j=0;j<=i;j++)
out[j][N-1-i+j] = Character.getNumericValue(inString.charAt(index++));
//prints the output
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
System.out.print(out[i][j] + "\t");
}
System.out.println();
}
}

Categories