1
votes

"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
1
Do you only want to print the result, or actually have an int[][] matrix with the rows/columns deleted?Kevin Cruijssen
You've got code that finds and removes one occurrence of max If you want to remove multiple occurrences of max, you'll have to repeat that logic multiple times: in other words, you need a loop.Kevin Anderson

1 Answers

0
votes

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.