Frage

Für meine Datenstrukturen projizieren, das Ziel ist in einer angegebenen Datei mit über 10.000 Songs mit Künstlern, Titel und Text deutlich gekennzeichnet, und jeder Song zu lesen ist über eine Leitung mit einem einzelnen Anführungszeichen getrennt. Ich habe diesen Code geschrieben, um die Textdatei zu analysieren, und es funktioniert, mit einer Laufzeit von knapp 3 Sekunden
Lesen Sie die 422k Textzeilen
Erstellen Sie einen Song Objekt
Add sagte Song zu einem Arraylist

Der Parsing-Code ich geschrieben habe, ist:

if (songSource.canRead()) {  //checks to see if file is valid to read
    readIn= new Scanner(songSource);
    while (readIn.hasNextLine()) {
 do {
     readToken= readIn.nextLine();

             if (readToken.startsWith("ARTIST=\"")) {
  artist= readToken.split("\"")[1];
      } 
      if (readToken.startsWith("TITLE=\"")) {
  title= readToken.split("\"")[1];
      } 
      if (readToken.startsWith("LYRICS=\"")) {
  lyrics= readToken.split("\"")[1];
      } else {
  lyrics+= "\n"+readToken;
      }//end individual song if block
 } while (!readToken.startsWith("\"")); //end inner while loop

    songList.add(new Song(artist, title, lyrics));

    }//end while not EOF 
} //end if file can be read 

Ich sprach mit meinem Intro to Algorithms Professor über den Code für dieses Projekt, und er stellte fest, dass ich versuchen sollte defensiveren in meinem Code zu Inkonsistenzen in Daten, die von anderen Personen zur Verfügung gestellt werden können. Ursprünglich war ich mit if / else Blöcken zwischen dem Künstler, Titel und Text Feldern und auf seinem Vorschlag, den ich, wenn Aussagen sequentiell geändert. Während ich seinen Punkt sehen kann, diesen Code am Beispiel, wie kann ich über so dass für die Eingabe Inkonsistenzen defensiver sein?

War es hilfreich?

Lösung

Sie gehen davon aus, dass der Eingang perfekt. Wenn man sich die Art und Weise Ihre Anwendung aussehen wird zZ auf der Grundlage eines schnellen Lese Ihres Algorithmus die Daten wie diese

aussehen würde
ARTIST="John"
TITLE="HELLO WORLD"
LYRICS="Sing Song All night long"
"

Aber betrachten wir den Fall

ARTIST="John"
TITLE="HELLO WORLD"
LYRICS="Sing Song All night long"
"
ARTIST="Peter"
LYRICS="Sing Song All night long"
"

Basierend auf Ihren Algorithmus, haben Sie jetzt zwei Songs als charakterisierten

songList = { Song("JOHN", "HELLO WORLD", "Sing Song All night long"),
             Song("Peter", "HELLO WORLD", "Sing Song All night long") }

Mit dem aktuellen Algorithmus, der Künstler und Titel freigelegt und wird in dem 2. Song auftauchen, obwohl sie nicht definiert wurden. Sie benötigen drei Variablen zurücksetzen.

in Ihr sonst Sie Dumping nur die komplette Linie in Texten. Was ist, wenn Sie bereits deutsche Übersetzung herausgezogen, zwingende Sie jetzt. Testfall

 ARTIST="John"
 LYRICS="Sing Song All night long"
 TILET="HELLO WORLD"
 "

Betrachten Sie diesen Datensatz in einen Fehlerzustand zu senden. Also, wenn die Batch-Lese abgeschlossen ist, kann eine Fehlermeldung erzeugt und fixiert werden.

Sehen Sie sich auch nur EOF nachdem ein Künstler in gelesen. Was passiert, wenn der EOF auftritt, während die Künstler lesen und die Datei endet nicht in“. Sie werden eine Ausnahme dorthin zu gelangen. In Ihrem do / während eines anderen hinzufügen Check für hasNextLine ()

Andere Tipps

Ich würde ersetzen z.

artist= readToken.split("\"")[1];

mit

String[] parts = readToken.split("\"");
if(parts.length >= 2) artist = parts[1];
else continue;

Weitere Modifikationen würden gehören:

  1. Zurücksetzen der lokalen Variablen (so dass Sie nicht versehentlich den falschen Künstler für einen Song zu tun bekommen, wenn kein Künstler für einig Lied nach dem erst zugeführt wird)
  2. entscheiden, was zu tun ist, wenn einige Daten fehlen - tun Sie immer noch das Lied der Songliste hinzufügen möchten

In der realen Welt gibt es einige Garantien in Bezug auf die Datenintegrität gemacht. Im Fall des mit Benutzereingabe zu tun (ob von stdin oder einer Datei) gibt es einig Projekt definiert Paradigma für den Benutzer eines Problems benachrichtigt, die Aufmerksamkeit erfordert.

Zum Beispiel, wenn ein Compiler kompiliert Code oder ein Shell Ausführen eines Skripts eine Inkonsistenz auftritt, es könnte stoppen und die Zeile gedruckt werden die Inkonsistenz mit einer zweiten Zeile darunter enthält, die den „^“ -Symbol verwendet den Ort des Problems, um anzuzeigen, .

Also hier sind einige grundlegende Frage, sich zu fragen:
1. Ist jede Linie garantiert jedes Feld enthalten?
2. Ist die Reihenfolge der Felder gewährleistet?

Wenn diese Bedingungen des Eingangs Vertrag sind und verletzt werden, sollten Sie ignorieren / berichten über die Linie. Wenn sie nicht Bedingungen des Eingangs sind, dann müssen Sie es zu handhaben .. was Sie zur Zeit nicht.

Ich sehe ein paar Dinge, die hier Jason fehlen.

Ich denke, die, wenn / sonst in Ordnung ist, und es wird nicht die Logik ändern. Allerdings sollten Sie den Umfang Ihrer Variablen so weit wie möglich einzuschränken. Durch die Deklaration Künstler, Titel, usw. innerhalb der while-Schleife, so werden diese auf null initialisiert werden (oder was auch immer) so, wenn ein Eintrag der Künstler fehlt, dann wird es nicht der letzte Eintrag Wert erhalten.

Auch, was passiert, wenn Titel, Künstler, hat usw. ein Zitat in dem? Wie ist das gehandhabt? Wie über die deutsche Übersetzung erscheinen, die mehrere Linien richtig?

sein

Was passiert, wenn ein unbekanntes Feld ist - vielleicht eine falsche Schreibweise? Es wird bis zum Ende der deutschen Übersetzung hinzugefügt werden, die nicht richtig zu sein scheint. Erst wenn die deutsche Übersetzung Feld gefunden wurde, sollten Sie es anhängen. Wenn Text null ist, dann wird es mit „null“ beginnen.

Hier sind einige Probleme, die angegangen werden könnten:

  • Der Code geht davon aus, dass es keine Leerzeichen ist vor (zum Beispiel) "ARTIST", kein rund um die Zeichen "=" und so weiter.

  • Der Code geht davon aus, dass die Schlüsselwörter in Großbuchstaben sind. Jemand könnte Klein- oder gemischten Fall verwenden.

  • Der Code geht davon aus, dass eine Linie, die nicht mit keyword=\" startet eine Fortsetzung des Textes des Liedes. Was aber, wenn der Benutzer eingegeben ARTOST="Sting"? Oder was, wenn der Benutzer zwei Linien für einen Künstlernamen zu verwenden versucht?

Schließlich, ich bin nicht davon überzeugt, dass das Ersetzen "else if" mit "wenn" in diesem Fall hat hat einen Unterschied zu der Robustheit des Codes.

Deal mit Ausnahmen (Ich denke, Scanner InputMismatchException für ein ungültiges Zeichen werfen konnte).

Es sieht aus wie die do { } while (...) kann eine Endlosschleife, wenn die Datei ist schlecht ausgebildet, und das Ende der Datei erreicht ist.

Nichts hindert artist oder title von leer zu sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top