Hallo, ich komme nicht weiter bei folgender Aufgabenstellung:
Es soll ein Agent programmiert, welcher eigenständig durch ein gegebenes Labyrinth manövrieren kann, um vom Eingang zum Ausgang zu gelangen. Das Labyrinth ist innerhalb einer Datei als Matrix aus „O“ und „X“ codiert, die „O“s bilden dabei die begehbaren Wege. Der Eingang ist stets oben links, der Ausgang stets unten rechts. Die Größe des Labyrinthes ist variabel, die Anzahl der Zeilen und Spalten wird mit einer Datei mitgeliefert:
z.b sieht es so aus;
5
5 OXXOX
OOOOX
XXXOX
XOOOO
XXXXO
Die Datei soll als Kommandozeilenparameter an die main-Methode übergeben werden.
Wie kriege ich das mit dem Einlesen hin. Und wie übergebe ich eine Datei an die main- Methode?
Irgendwie so:
Java:
publicLabyrinth(String datei)throwsException{BufferedReader in =newBufferedReader(newFileReader(file))// Datei oeffnen// Zeilen und Spalten auslesen// Array erstellen und fuellen}
Die Frage ist auch wenn z.b in der Datei nicht 5 Spalten und 5 Zeilen steht. Sondern 10 und 12. Wie erkennt das Programm dann das?
spalten = Länge des Strings irgendeiner Zeile, vorausgesetzt, die Datei ist gültig (=valide Form), aber das lassen wir mal außen vor
zeilen = eingelesene Zeilen.
Und das gilt für alle.
Wenn du in die Kommandozeile "java MainClass" eingibst ist MainClass die Hauptklasse deines Programms (vorher mit javac MainClass.java kompilieren!). Schreibst du in die MainClass-Datei (*.java) folgendes:
Ach so, in deinem Eingangspost stand es halt mehrzeilig und ich dachte, dass es so in der Datei drinsteht.
Mein Lösungsvorschlag:
Wenn 57XOXOXOXO... drin steht, dann sind es 5 Zeilen und 7 Spalten.
Wenn aber z.B. 258XOXOXOX... drin steht, dann sind es entweder 25 Zeilen/8 Spalten oder 2 Zeilen und 58 Spalten.
Damit wäre diese "Nomenklatur" nicht eindeutig, wenn Du z.B. 10/12 Spalten brauchst schon. Aber alles mit 3 Ziffern nicht.
Wenn du das willst, dann könnte es so aussehen:
0505XOXO... = 05 (=5) Zeilen + 05 (=5) Spalten
0510XOXO... = 05 (=5) Zeilen + 10 (=10) Spalten
Zeile und Spalte dürfen nicht größer sein als 99.
Alle Angaben der SubStrings beziehen sich auf den eingelesen einzeiligen String.
D.h.
zeile = ToInteger (Substring Zeichen 1 bis 2)
spalte = ToInteger (Substring Zeichen 3 bis 4)
labyrinthString = Substring Zeichen 5 bis Ende (über StringLen() erhältlich)
Dann um das Zeilenweise anzuzeigen sollte das hier gehen:
for (int i = 0; i < zeile; i++) {
for (int j = 0; i < spalte; i++) {
System.out.print(labyrinthString[i+j]);
}
System.out.println(""); //zeilenumbruch (= System.out.print("\n"))
}
Ich habe noch eine Beispieldatei gefunden, diese sieht so aus:
1718OXXXXXXXXXXXXXXXXXOOOOXXXXXXXXXXXXXXXXXOXXXXXXXXXXXXXXXOOOOOOOOXXXXXXXXXXXXXXOXXXXXXXXXXXXXXXXXOOOXOOOXXXXXXXXXXXXXOXOXOXXXXXXXXXXXXXOOOXOXXXXXXXXXXXXXXXXXOOOOOXXXXXXXXXXOOOOXXXXXXXXXXXXXXOXXOXXXXXXXXXXXXXXXXXOXXXXXXXXXXXXXXXXXOOOXXXXXXXXXXXXXXXXXOXXXXXXXXXXXXXXXXXOOOXXXXXXXXXXXXXXXXXOOXXXXXXXXXXXXXXXXXOO
Es soll wsl 17 und 18 sein.
Dann muss es gehen wie du sagst:
Wenn du das willst, dann könnte es so aussehen:
0505XOXO... = 05 (=5) Zeilen + 05 (=5) Spalten
0510XOXO... = 05 (=5) Zeilen + 10 (=10) Spalten
Zeile und Spalte dürfen nicht größer sein als 99.
Alle Angaben der SubStrings beziehen sich auf den eingelesen einzeiligen String.
D.h.
zeile = ToInteger (Substring Zeichen 1 bis 2)
spalte = ToInteger (Substring Zeichen 3 bis 4)
labyrinthString = Substring Zeichen 5 bis Ende (über StringLen() erhältlich)
importjava.io.BufferedReader;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;importjava.util.logging.Level;importjava.util.logging.Logger;/**
*
* @author florian
*/publicclassLabyrinth{/**
* @param args the command line arguments
*/publicstaticvoidmain(String[] args){try{String filename = args[0];try{BufferedReader in =newBufferedReader(newFileReader(filename));try{// Here the "main" code is executedString firstline = in.readLine();// reads the 1st lineint zeile =Integer.parseInt(firstline.substring(0,2));int spalte =Integer.parseInt(firstline.substring(2,4));String labyrinthString = firstline.substring(4, firstline.length());for(int i =0; i < labyrinthString.length(); i++){System.out.print(labyrinthString.charAt(i));if((i+1)% spalte ==0){System.out.println("");}}}catch(IOException ex){Logger.getLogger(Labyrinth.class.getName()).log(Level.SEVERE,null, ex);}}catch(FileNotFoundException ex){// Self-explaining :-)Logger.getLogger(Labyrinth.class.getName()).log(Level.SEVERE,null, ex);}}catch(IndexOutOfBoundsException e){// Wird geworfen wenn args[0] nicht existiertSystem.out.println("Fehler, keine Datei übergeben.");}}}
Habe es getestet und es funktioniert mit allen Beispielen hier. Aber wie gesagt, darauf achten, dass die ersten vier Zeichen des "Labyrinthtexts" mit Zahlen belegt sind, d.h. nicht wie oben mit 57OO... sondern 0507...
Sonst schmeißt Java eine Exception dass die Konvertierung nicht erfolgt ist.
Im Prinzip können alle Inhalte in den Exceptions (außer die IndexOutOfBounds ganz unten), also die mit Logger.getLogger(...); weggehauen werden, die wurden halt von NetBeans so generiert.
Danke für deine Antwort. Wsl geht es wirklich nicht anders, als das 4 Zahlen am Anfang braucht. Das Problem ist, dass wir mit dem try catch noch nichts zu tun hatten. Würde das auch ohne gehen irgendwie ?
Hallo frage doch ab, ob args nicht leer ist.
Genau so kannst du abfragen ob es die Datei existiert.
Und genauso kannst du prüfen ob firstLine eine gewisse notwendige Länge an Zeichen hat.
Somit musst du keine Exception abfangen. Ich finde das beispiel von @olfibits hat drei unnötige try catch.
Hi @truesoul
Im Prinzip ist das natürlich richtig. Aber da NetBeans bei jeder unabgefangenen Exception mosert, gehe ich halt immer auf "Surround block with try-catch" und fertig. Bei args[0] habe ich die IndexOutOfBounds deshalb genommen, weil es schneller ging als eine Überprüfung. Aber sonst hast du natürlich recht.
Hallo frage doch ab, ob args nicht leer ist.
Genau so kannst du abfragen ob es die Datei existiert.
Und genauso kannst du prüfen ob firstLine eine gewisse notwendige Länge an Zeichen hat.
Somit musst du keine Exception abfangen. Ich finde das beispiel von @olfibits hat drei unnötige try catch.
Im Prinzip ist das natürlich richtig. Aber da NetBeans bei jeder unabgefangenen Exception mosert, gehe ich halt immer auf "Surround block with try-catch" und fertig. Bei args[0] habe ich die IndexOutOfBounds deshalb genommen, weil es schneller ging als eine Überprüfung. Aber sonst hast du natürlich recht.
Nur die IndexOutOfBounds ist überflüssig (und sollte auch nicht gefangen werden), die anderen beiden müssen gefangen oder weitergeworfen werden, dass sind checked Exceptions.
Man kann sie auch nicht durch Prüfen verhindern, da die Datei zwischen Prüfung und Interaktion immer noch gelöscht werden oder z.B. der Stream während des Lesens abbrechen kann.
Nur die IndexOutOfBounds ist überflüssig (und sollte auch nicht gefangen werden), die anderen beiden müssen gefangen oder weitergeworfen werden, dass sind checked Exceptions.