2016-05-13 16 views
1

Ich habe eine int [] [] a, die sowohl positive als auch negative ganze Zahlen enthält. Ich möchte nur die positiven ganzen Zahlen in ein anderes Array kopieren, int [] [] result. Hier ist mein Versuch:Wie entferne ich Platzhalterwerte aus einem zweidimensionalen Array in Java?

for(int r = 0; r < a.length; r ++) 
     { 
      int aC = 0; 
      for(int resC = 0; resC < result[r].length; resC++) 
      { 
       while (a[r][aC] < 0) 
       { 
        aC++; 
       } 
       result[r][resC] = a[r][aC]; 
       aC++; 
      } 
     } 

Wenn ich das Programm führen Sie es auf Linie abstürzt 6 zitierte einen java.lang.ArrayIndexOutOfBoundsException: 3 Fehler. Wenn ich den Debugger laufe, kann ich sehen, dass es so lange wie r = 0 funktioniert.

Ich fühle mich wie ich vermisse etwas offensichtlich, aber nachdem ich es für eine Stunde starrte ich immer noch nicht das Problem finden kann.

Antwort

0

Sie haben keine Schranken für

Prüfung
a[r][aC] 

so

while (a[r][aC] < 0) 

fehl.

Auch wenn Sie jetzt Arrays ungleicher Größe haben, wäre es besser, zu einer ArrayList hinzuzufügen, und dann bei Bedarf zu einem Array zu konvertieren.

So etwas wie

ArrayList <Integer> posValues = new ArrayList <Integer>(); 
for(int r = 0; r < a.length; r ++) 
{ 
     for(int c = 0; c < a[r].length; c++) 
     { 
      if (a[r][c] > 0) 
      { 
       posValues.add (new Integer (a[r][c])); 
      } 
     } 
} 
+0

Aber wenn während (a [r] [AC] <0) nicht wäre nicht das Programm Voraus zu führen [r] [RESC] = a [r] [aC];? Ich hatte den Eindruck, dass der Fehler, den ich erhielt, darauf hinwies, dass ich einen Wert anrufe, wo es keinen gab. Könnten Sie bitte Ihre Antwort klären? Vielen Dank. – user6329147

+0

Wenn der Wert von 'aC' größer ist als die Länge des Unterarrays a [r], wird eine ArrayIndexOutOfBoundsException ausgelöst - das ist, was ich unter' no bounds checking' verstehe –

0

Wenn wir die innere for Schleife erreichen, wir haben keine Garantien über result[r], und so r sehr gut außerhalb der Grenzen liegen. Statt dessen:

for (int r = 0; r < a.length; r++) { 
     int aC = 0; 
     for (int resC = 0; resC < result[r].length; resC++) { 

wird der Code sicherer so aussehen:

for (int r = 0; r < a.length; r++) { 
     int aC = 0; 
     for (int resC = 0; resC < a[r].length; resC++) { 

Weil wir wissen, dass a[r] in Grenzen sein wird.

Aber das ist nicht annähernd genug. Die innerste while-Schleife versucht wahrscheinlich auch, auf einen Index außerhalb der Grenzen zuzugreifen, in der Tat ist es unvermeidlich, wenn Sie mindestens einen negativen Wert haben. Eigentlich müssen Sie die Schleifenlogik dort, invertieren, anstatt über Indizes in Ergebnis, iterieren es macht mehr Sinn, über Indizes in der Quelle zu iterieren. So:

for (int r = 0; r < a.length; r++) { 
     int resC = 0; 
     for (int aC = 0; aC < a[r].length; aC++) { 
      if (a[r][aC] < 0) { 
       continue; 
      } 
      result[r][resC++] = a[r][aC]; 
     } 
    } 

schließlich mit Variablen umbenannt, es viel einfacher wird, zu verstehen, was der Code versucht zu tun:

for (int row = 0; row < source.length; row++) { 
     int targetCol = 0; 
     for (int col = 0; col < source[row].length; col++) { 
      if (source[row][col] < 0) { 
       continue; 
      } 
      target[row][targetCol++] = source[row][col]; 
     } 
    } 
2

Warum haben 3 Schleifen? Nur Schleife Ihre 2 Dimensionen und kopieren positive Werte:

for (int r = 0; r < a.length; r++) 
    for (int c = 0; c < a[r].length; c++) 
     if (a[r][c] > 0) 
      result[r][c] = a[r][c]; 

Es sei denn natürlich die Werte verdichten wollen (Frage sagen nicht, aber Code Versuch scheint darauf hinzudeuten). Oder wollten Sie auch abschneiden?

Input    Copy   Condensed  Truncated 
-1 1 2   0 1 2   1 2 0   1 2 
-1 -1 3 ==> 0 0 3 ==> 3 0 0 ==> 3 
4 -1 5   4 0 5   4 5 0   4 5 

Hier ist eine Version mit Verkürzungs:

int[][] result = new int[a.length][]; 
for (int r = 0; r < a.length; r++) { 
    int count = 0; 
    for (int c = 0; c < a[r].length; c++) 
     if (a[r][c] > 0) 
      count++; 
    result[r] = new int[count]; 
    for (int c = 0, cRes = 0; c < a[r].length; c++) 
     if (a[r][c] > 0) 
      result[r][cRes++] = a[r][c]; 
} 
Verwandte Themen