2009-11-26 21 views
5

Tengo una simple matriz, algo así como esteCómo eliminar una fila en la matriz bidimensional

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 

lo tanto, vamos a llamar a este matrix[5][9]. Deseo eliminar ahora 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 
+0

Además, si usted está poniendo if ((input.data [j] [i] == 10)), ¿su código no va a marcar cada fila como válida a menos que contenga todos los 10? –

Respuesta

8

Aquí hay una clase de muestra que puede ejecutar que creo que hace lo que está buscando. La eliminación de filas de las matrices 2D es un asunto delicado porque, como dijo @KalebBrasee, no se puede "eliminar" realmente, sino que se debe crear una matriz 2D totalmente nueva. ¡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); 
    } 
} 
+0

Estoy probando el código ahora y obtengo una ArrayIndexOutOfBoundsException cuando llegue a 10. – AlexT

+0

Creo que ya descubrí el problema. ¿Hay alguna posibilidad de que pueda mirar mi edición para ver si se puede resolver? – AlexT

+0

Definitivamente funciona bien como está pegado aquí, así que eche un vistazo a sus ediciones. –

1

No se puede quitar elementos de la Java incorporado en la matriz de datos estructura. Deberá crear una nueva matriz que tenga una longitud inferior a la primera matriz y copiar todas las matrices en esa matriz, EXCEPTO la que desee eliminar.

+0

Como estoy usando la clase Matrix para pasar una Matriz, no hay problema con simplemente tomar una y sacar una Matriz más corta. Me quedé atrapado en cómo iba a "eliminar" esa fila de mi nueva matriz una vez que había encontrado el valor dentro de una celda. – AlexT

5

Utilice System.arraycopyo utilice 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.

+2

Creo que solo debes poner% 20 para los espacios – Yishai

0

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 se excluye la función concat() usado para concatenar dos matrices, se hace en una sola línea:
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
Ver this question también. Ahí es donde viene el código para la función concat().

(2)
Este método es más rápido y solo utiliza funciones ya disponibles.

1

En el y tiene que volver a crear 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 compilar la matriz basada en Colecciones (ArrayList<ArrayList<Double>>), allí puede eliminar una fila fácilmente.

Volver a matrices - la idea es recoger todas las filas (double [] arrays) que desea guardar, crear una matriz resultado con esas filas y reemplazar el viejo con el nuevo en el 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); 
} 
0

Mi sintaxis de Java es un poco oxidado, pero los siguientes, si se trata como pseudocódigo trabajará

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 
0

Dado que no puede evitar la creación de nueva matriz 2D para contener el post-quitar los datos, en primer lugar, crear una nueva 2D int [] [] b con la misma dimensión que a [] []. en segundo lugar, recorra un [] [], asigne aab y mueva b row cuando a contenga un valor específico. y cordura verificar 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]); 
     } 
    } 
} 
0

Puede que no sea una solución exacta, sino un concepto de cómo se puede lograr utilizando System.arraycopy.

En el siguiente ejemplo, deseo copiar todas las filas excepto la primera fila. En su caso, puede omitir aquellas 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

Cuestiones relacionadas