2016-04-15 7 views
1

Also habe ich diese Datei, die nur mit Ganzzahlen gefüllt ist. Ich möchte, wenn möglich, in der Lage sein, eine Datei zu lesen, die Leerzeichen enthalten kann oder nicht, die jede Ganzzahl abgrenzen.Lesen einer Datei mit ganzen Zahlen, die durch Leerzeichen getrennt sein können oder können

Hier sind zwei visuelle Beispiele.

Die erste ist Ganzzahlen, die nicht durch Leerzeichen begrenzt sind, während die zweite sind.

Erstes Beispiel:

020030090 
000907000 
900208005 
004806500 
607000208 
003102900 
800605007 
000309000 
030020050 

Zweites Beispiel:

0 3 8 0 12 0 15 16 6 0 4 0 0 0 0 0 
0 11 5 0 1 0 0 14 13 0 3 9 12 7 0 0 
0 0 0 0 6 0 0 0 0 12 0 14 0 0 0 16 
10 16 0 6 2 13 0 0 0 8 7 0 0 0 0 0 

3 10 1 0 13 0 0 15 0 9 0 16 5 0 0 0 
0 0 16 0 0 0 0 11 14 0 13 12 0 3 0 0 
4 0 7 8 0 0 12 9 0 0 0 0 0 0 11 0 
0 6 0 0 16 0 0 0 11 5 0 0 15 0 0 2 

11 0 0 12 0 0 8 2 0 0 0 1 0 0 14 0 
0 7 0 0 0 0 0 0 3 11 0 0 8 16 0 9 
0 0 13 0 3 6 0 7 16 0 0 0 0 11 0 0 
0 0 0 2 5 0 14 0 15 0 0 4 0 13 7 1 

0 0 0 0 0 14 5 0 0 0 16 2 13 0 8 10 
14 0 0 0 8 0 9 0 0 0 0 11 0 0 0 0 
0 0 6 15 7 1 0 3 12 0 0 13 0 2 5 0 
0 0 0 0 0 15 0 12 1 14 0 3 0 6 16 0 

Hinweis:

ich auch, dass die zweite Datei abgegrenzt wird möglicherweise nicht hinzufügen möchte um den gleichen Betrag. Dies bedeutet, dass eine Ganzzahl ein Leerzeichen nach ihr und eine andere Ganzzahl nach 10 Leerzeichen enthalten kann.

Was ich versucht habe:

ich versucht habe, mit dem split ("\ s +") in Kombination mit dem replaceAll ("", "„) aber dies nicht in den zweiten Arbeit Beispiel, weil es mehr Leerzeichen hätte und somit die Split-Funktion nicht funktionieren würde.

Ich habe versucht mit replaceAll ("", "") so, dass sie überhaupt keine Leerzeichen haben. Dann konvertierte ich die Zeichenfolge in ein Char-Array, aber das stellte Probleme mit ganzen Zahlen größer als eine Ziffer dar (würde auch mit dem zweiten Beispiel nicht funktionieren).

Code:

public void initializeGrid(int grid[][], String fileName) throws FileNotFoundException, IOException 
{ 
     Scanner read = new Scanner(Paths.get(fileName)); 
     int value; 

     for (int i = 0; i < ROWS; i++) 
     {  
      String line = read.nextLine(); 
      String [] numbers = line.trim().split("\\s+"); 

      for (int j = 0; j < COLUMNS; j++) 
      {  
       value = Integer.parseInt(numbers[j]); 
       grid[i][j] = value; 
      } 
     } 
} 
+0

Wenn die Ganzzahlen nicht begrenzt sind, woher weißt du dann, wo einer endet und der nächste beginnt? – dnault

+0

@dnault Ich weiß, dass es ein Problem ist, aber wenn der Benutzer den Pfad zu der Datei eingibt, woher weiß ich, dass jede ganze Zahl durch Leerzeichen begrenzt ist? Deshalb habe ich am Anfang gesagt, wenn das möglich wäre. Es ist viel einfacher, sich keine Sorgen über diese Situation zu machen, aber ich würde gerne mit dieser Situation umgehen, wenn ich nicht kann, weil beide Dateien gültig sind. –

+0

Oh, ich verstehe. Im ersten Fall ist garantiert, dass jede ganze Zahl im Bereich "[0-9]" liegt. Der zweite Fall ist für den Fall erforderlich, dass die ganzen Zahlen größer als 9 sein können. – dnault

Antwort

1

Nach der Empfehlung von @dnault in den Kommentaren oben, hier ist eine Implementierung, die die Java Collection Rahmen anstelle eines 2d int Array verwendet. Dieser Ansatz hat gegenüber einem 2d-Array den Vorteil, dass der List für jede Zeile genau so viele Einträge enthält wie benötigt. Wenn in Arrays eine Zeile weniger als COLUMN Werte aufweist, enthält das Array Nullen für alle verbleibenden Werte.

public List<List<Integer>> readFile(String fileName) 
     throws FileNotFoundException, IOException { 
    BufferedReader br = Files.newBufferedReader(Paths.get(fileName)); 
    List<List<Integer>> values = new ArrayList<>(); 


    for(String line; (line = br.readLine()) != null;){ 
     String[] splitLine = line.trim().split("\\s+"); 

     if(splitLine.length < 2) 
      values.add(parseSingleDigitValues(splitLine[0].toCharArray())); 
     else 
      values.add(parseDelimitedValues(splitLine)); 

    } 

    return values; 
} 

private List<Integer> parseSingleDigitValues(char[] line) { 
    List<Integer> values = new ArrayList<>(); 
    for(char c: line){ 
     values.add(Integer.parseInt(String.valueOf(c))); 
    } 
    return values; 

} 

private List<Integer> parseDelimitedValues(String[] line) { 
    List<Integer> values = new ArrayList<>(); 
    for(String str :line) 
     values.add(Integer.parseInt(str)); 
    return values; 
} 

Das resultierende List<List<Integer>> dann leicht in eine der folgenden Methode int Array 2D umgewandelt werden können:

private int[][] asArray(List<List<Integer>> lists){ 
    int s1 = lists.size(); 
    int s2 = 0; 
    for(List<Integer> sublist : lists){ 
     if(sublist.size() > s2) 
      s2 = sublist.size(); 
    } 

    int[][] arr = new int[s1][s2]; 
    for(int i = 0; i < lists.size(); i++){ 
     List<Integer> sublist = lists.get(i); 
     for(int j = 0; j < sublist.size(); j++){ 
      arr[i][j] = sublist.get(j); 
     } 
    } 
    return arr; 
} 

EDIT Am Ende, wenn Sie deutlich die Belastung dann Ihren Code/api dokumentieren ist auf den Benutzer, um es richtig zu verwenden. Ich empfehle Ihnen, in Ihrer API für Einfachheit zu sorgen: Sagen Sie dem Benutzer, dass er eine durch Leerzeichen getrennte Datei bereitstellen muss. Sie können dann eine Dienstprogrammklasse bereitstellen, die eine Datei ohne Trennzeichen in eine durch Leerzeichen getrennte Datei konvertiert.

+0

Genau das habe ich mir gedacht. Ich wollte einfach nicht, dass der Benutzer eine Datei ohne Leerzeichen eingibt und sie sehen, dass es nicht richtig funktioniert hat, aber ich denke, dass es ausreicht, wenn man ihnen sagt, dass sie durch Leerzeichen begrenzt werden soll. –

+0

Genau. Das ist, was die API-Dokumentation tun soll --- sagen Sie dem Benutzer, wie man die API benutzt. Solange es eindeutig dokumentiert ist, ist es Sache des Benutzers, Ihren Richtlinien zu folgen. Wenn Sie sich für Leerzeichen-Trennzeichen entscheiden, empfehle ich Ihnen, eine Ausnahme auszulösen, wenn Leerzeichen nicht verwendet oder falsch verwendet werden (an irgendeinem Punkt). Dies würde dem Benutzer helfen, das Problem so früh wie möglich im Debugging-Prozess zu identifizieren. –

Verwandte Themen