Pregunta

Tengo una matriz simple, algo así

1 2 3 4 5 6 7 8 9
6 2 7 2 9 6 8 10 5
2 6 4 7 8 4 3 2 5
9 8 7 5 9 7 4 1 10
5 3 6 8 2 7 3 7 2

Entonces, llamemos a esto matrix[5][9]. Ahora deseo eliminar cada fila dentro de esta matriz que contiene un cierto valor, en este caso 10, por lo que me queda ...

1 2 3 4 5 6 7 8 9
2 6 4 7 8 4 3 2 5
5 3 6 8 2 7 3 7 2
¿Fue útil?

Solución

Aquí hay una clase de muestra que puedes ejecutar que creo que hace lo que estás buscando. Eliminar filas de matrices 2D es un asunto complicado porque, como dijo @KalebBrasee, no se puede & Quot; eliminar & Quot; ellos, sino que tienes que hacer una nueva matriz 2D en su lugar. ¡Espero que esto ayude!

import java.util.ArrayList;
import java.util.List;


public class Matrix
{
    private double[][] data;

    public Matrix(double[][] data)
    {
        int r= data.length;
        int c= data[0].length;
        this.data= new double[r][c];
        for(int i = 0; i < r; i++) {
            for(int j = 0; j < c; j++) {
                    this.data[i][j] = data[i][j];
            }
        }
    }

    /* convenience method for getting a 
       string representation of matrix */
    public String toString()
    {
        StringBuilder sb = new StringBuilder(1024);
        for(double[] row : this.data)
        {
            for(double val : row)
            {
                sb.append(val);
                sb.append(" ");
            }
            sb.append("\n");
        }

        return(sb.toString());
    }

    public void removeRowsWithValue(final double value)
    {
            /* Use an array list to track of the rows we're going to want to 
               keep...arraylist makes it easy to grow dynamically so we don't 
               need to know up front how many rows we're keeping */
        List<double[]> rowsToKeep = new ArrayList<double[]>(this.data.length);
        for(double[] row : this.data)
        {
            /* If you download Apache Commons, it has built-in array search
                      methods so you don't have to write your own */
            boolean found = false;
            for(double testValue : row)
            {
                            /* Using == to compares doubles is generally a bad idea 
                               since they can be represented slightly off their actual
                               value in memory */
                if(Double.compare(value,testValue) == 0)
                {
                    found = true;
                    break;
                }
            }

                    /* if we didn't find our value in the current row, 
                      that must mean its a row we keep */
            if(!found)
            {
                rowsToKeep.add(row);
            }
        }

            /* now that we know what rows we want to keep, make our 
               new 2D array with only those rows */
        this.data = new double[rowsToKeep.size()][];
        for(int i=0; i < rowsToKeep.size(); i++)
        {
            this.data[i] = rowsToKeep.get(i);
        }
    }

    public static void main(String[] args)
    {
        double[][] test = { {1, 2, 3, 4, 5, 6, 7, 8, 9},
                            {6, 2, 7, 2, 9, 6, 8, 10, 5},
                            {2, 6, 4, 7, 8, 4, 3, 2, 5},
                            {9, 8, 7, 5, 9, 7, 4, 1, 10},
                            {5, 3, 6, 8, 2, 7, 3, 7, 2} };

            //make the original array and print it out          
        Matrix m = new Matrix(test);
        System.out.println(m);

            //remove rows with the value "10" and then reprint the array
        m.removeRowsWithValue(10);
        System.out.println(m);
    }
}

Otros consejos

Use System.arraycopy o use java.util.List en lugar de matrices. ArrayList tiene acceso rápido a elementos aleatorios y un método lento remove, es lo contrario con LinkedList. Tienes que elegir por ti mismo.

No puede eliminar elementos de la estructura de datos de matriz incorporada de Java. Tendrá que crear una nueva matriz que tenga una longitud menor que la primera matriz y copiar todas las matrices en esa matriz, EXCEPTO la que desea eliminar.

En el y debe recrear la matriz y descartar la anterior. No es posible cambiar la dimensión de una matriz existente: si desea este tipo de estructura de datos, debe construir la matriz basada en Colecciones (ArrayList<ArrayList<Double>>), allí puede eliminar una fila fácilmente.

Volver a las matrices: la idea es recopilar todas las filas (matrices dobles []) que desea conservar, crear una matriz de resultados con esas filas y reemplazar la anterior con la nueva en Matrix:

public void doSomethingWith(Matrix in) {
  List<double[]> survivingRows = new ArrayList<double[]>();
  for (double[] row:in.getRows()) {
    if (isAGoodOne(row)) {
      survivingRows.add(row);
    }
  }

  double[][] result = new double[survivingRows][];
  for (int i = 0; i < result.length; i++) {
    result[i] = survivingRows.get(i);
  }
  in.setArray(result);
}

Mi sintaxis de Java está un poco oxidada, pero lo siguiente, si se trata como pseudocódigo, funcionará

public Matrix removeRows(Matrix input) {
    int[][] output = new int[input.numRows][input.numColumns]();
    int i = 0;
    for (int[] row : input.rows()) {      // Matrix.rows() is a method that returns an array of all the rows in the matrix
        if (!row.contains(10)) {
            output[i] = row;
        }
    }
    return output

Mi opinión:

import java.util.Arrays;

public class RemoveArrayRow {
    private static <T> T[] concat(T[] a, T[] b) {
        final int alen = a.length;
        final int blen = b.length;

        if (alen == 0) {
            return b;
        }

        if (blen == 0) {
            return a;
        }

        final T[] result = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), alen + blen);

        System.arraycopy(a, 0, result, 0, alen);
        System.arraycopy(b, 0, result, alen, blen);

        return result;
    }

    public static void main(String[] args) {
        double[][] d  = { {11, 2, 3, 4, 5, 6, 7, 8, 9, 0},
                          {12, 2, 3, 4, 5, 6, 7, 8, 9, 1},
                          {13, 2, 3, 4, 5, 6, 7, 8, 9, 2},
                          {14, 2, 3, 4, 5, 6, 7, 8, 9, 3},
                          {15, 2, 3, 4, 5, 6, 7, 8, 9, 4} };

        //remove the fourth row:

        // (1)
        double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));

        // (2)
        double[][] d2 = new double[d.length - 1][d[0].length];
        System.arraycopy(d, 0, d2, 0, 3);
        System.arraycopy(d, 4, d2, 3, 1);

        System.out.print(d1.length);
        System.out.print(d2.length);
    }
}

(1)
Si excluye la función concat() utilizada para concatenar dos matrices, se realiza en una línea:
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
Consulte esta pregunta también . De ahí proviene el código para la función (2).

<=>
Este método es más rápido y solo utiliza funciones ya disponibles.

Dado que no puede evitar crear una nueva matriz 2D para contener los datos eliminados después, en primer lugar, cree una nueva 2D int [] [] b con la misma dimensión que a [] []. en segundo lugar, recorra a [] [], asigne a a b y mueva la fila b hacia arriba cuando a contenga un valor específico. y la sanidad comprueban la última fila, que puede contener datos específicos.

public static int[][] remove(int[][] a, int v) {
    int r = a.length;
    int c = a[0].length;

    int[][] b = new int[r][c];

    int red = 0;
    boolean s = false;
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            b[i - red][j] = a[i][j];
            if (a[i][j] == v) {
                red += 1;
                if(i==r-1){
                    s = true;
                }
                break;
            }
        }
    }
    //check last row
    if(s){
    for(int i = r-red;i <r-red +1; i++ )
        for (int j = 0; j<c; j++){
            b[i][j] = 0;
        }
    }
    return b;
}

public static void main(String[] args){
    int[][] a = { {1, 2, 3, 4, 5, 6, 7, 8, 1},
            {6, 2, 7, 2, 9, 6, 8, 10, 5},
            {2, 6, 4, 7, 8, 4, 2, 2, 5},
            {9, 8, 7, 5, 9, 7, 4, 1, 1},
            {5, 3, 6, 8, 2, 7, 3, 1, 1} };

    print(remove(a, 10));


}

public static void print(int[][] a) {
    int r = a.length;
    int c = a[0].length;


    int red = 0;
    for (int i = 0; i < r; i++) {
        System.out.printf("\nrow %d, \n", i);
        for (int j = 0; j < c; j++) {
            System.out.printf("%d, ", a[i][j]);
        }
    }
}

Esto puede no ser una solución exacta sino un concepto de cómo puede lograrlo usando System.arraycopy.

En el ejemplo a continuación, quiero copiar todas las filas excepto la primera fila. En su caso, puede omitir las filas que contienen 10.

String[][] src = getSheetData(service, spreadSheetId, range);
String[][] dest = new String[src.length-1][src[0].length];

for (int i = 1; i < src.length; i++) {
System.arraycopy(src[i], 0, dest[i-1], 0, src[0].length-1);
}

Referencia: https://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy%28java.lang .Object,% 20int,% 20java.lang.Object,% 20int,% 20int% 29

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top