2009-11-26 24 views
5

Mam proste tablicę, coś w rodzaju tegoJak usunąć wiersz w tablicy dwuwymiarowej

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 

So, nazwijmy to matrix[5][9]. Pragnę teraz usunąć każdy wiersz w tej matrycy, która zawiera pewną wartość, w tym przypadku 10, więc ja zostaję z ...

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

Ponadto, jeśli jesteś wprowadzenie if ((input.data [j] [i] == 10)), czy twój kod nie oznaczy każdego wiersza jako prawidłowego, chyba że zawiera wszystkie 10? –

Odpowiedz

8

Oto przykładowa klasa, którą możesz uruchomić, a wierzę, że robi to, czego szukasz. Usunięcie wierszy z tablic 2D jest trudnym zadaniem, ponieważ jak powiedział @KalebBrasee, nie można ich naprawdę "usunąć", ale zamiast tego trzeba stworzyć zupełnie nową tablicę 2D. Mam nadzieję że to pomoże!

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

Próbuję teraz kod i otrzymuję wyjątek ArrayIndexOutOfBoundsException, gdy trafi 10. – AlexT

+0

Myślę, że wymyśliłem problem. Czy jest szansa, że ​​obejrzysz moją edycję, aby sprawdzić, czy można ją rozwiązać? – AlexT

+0

To na pewno działa poprawnie jako wklejone, więc przyjrzę się twoim zmianom. –

1

Nie można usunąć elementy z Java wbudowanej tablicy danych Struktura. Musisz utworzyć nową tablicę o długości o jeden mniej niż pierwsza tablica i skopiować wszystkie tablice do tej tablicy, Z WYJĄTKIEM tej, którą chcesz usunąć.

+0

Ponieważ używam klasy Matrix do przekazania Matrycy, nie ma problemu z po prostu wzięciem jednego i wyprowadzeniem krótszej Matrycy. Po prostu utknąłem na tym, jak chciałbym "usunąć" ten wiersz z mojej nowej Matrycy, gdy tylko znajdę wartość w komórce. – AlexT

5

Użyj System.arraycopylub użyj java.util.List zamiast tablic. ArrayList ma szybki dostęp do elementów losowych i powolną metodę remove, jest odwrotnie niż LinkedList. Musisz sam wybrać.

+2

Myślę, że po prostu trzeba wstawić% 20 dla przestrzeni – Yishai

0

My się:

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)
Jeśli wyklucza funkcję concat() używany złączenie dwóch tablic, to zrobić w jednym wierszu:
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
Zobacz this question również. Stąd pochodzi kod funkcji concat().

(2)
Ta metoda jest szybsza i korzysta tylko z już dostępnych funkcji.

1

Na i musisz odtworzyć tablicę i odrzucić starą. Zmiana wymiaru istniejącej macierzy nie jest możliwa - jeśli chcesz tego typu danych, powinieneś zbudować macierz na podstawie kolekcji (ArrayList<ArrayList<Double>>), dzięki czemu możesz łatwo usunąć wiersz.

Powrót do tablic - chodzi o to, aby zebrać wszystkie wiersze (double [] tablice), które chcesz zachować, należy utworzyć tablicę wyników z tych wierszy i zastąpienie starego z nowym na na 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

Moja składnia Java jest trochę zardzewiały, ale dodaje, jeśli traktowane jako Pseudokod zadziała

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

Ponieważ nie można uniknąć tworzenia nowej tablicy 2D zawierają po-usuniętych danych, po pierwsze, należy utworzyć nowy 2D int [] [] bz tym samym wymiarze co [] []. po drugie, przeprowadź pętlę przez [] [], przypisz a do b i przesuń b wiersz w górę, gdy zawiera określoną wartość. a zdrowie psychiczne sprawdza ostatni wiersz, który może zawierać określone dane.

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

To może nie być dokładne rozwiązanie, ale koncepcja, jak można to osiągnąć za pomocą System.arraycopy.

W poniższym przykładzie chcę skopiować wszystkie wiersze z wyjątkiem pierwszego wiersza. W twoim przypadku, można pominąć te wiersze, które zawierają 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); 
} 

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

Powiązane problemy