Domanda

Per proiettare le mie strutture di dati, l'obiettivo è quello di leggere in un file fornito contiene oltre 10000 canzoni con artista, titolo e testo ben segnalati, e ogni canzone è separata da una linea con un unico doppio preventivo. Ho scritto questo codice per analizzare il file di testo, e funziona, con un tempo di esecuzione di poco meno di 3 secondi per
leggere i 422K righe di testo
creare un oggetto canzone
add ha detto Song a un ArrayList

Il codice di analisi che ho scritto è:

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 

stavo parlando con la mia Introduzione agli algoritmi professore sul codice per questo progetto, e ha dichiarato che avrei dovuto cercare di essere più difensivo nel mio codice per consentire incoerenze nei dati forniti da altre persone. Originariamente ero utilizza if / else blocchi tra l'artista, i campi Testi titolo e, e il suo suggerimento ho cambiato a sequenziali se dichiarazioni. Mentre posso vedere il suo punto, utilizzando questo esempio di codice, come posso essere più sulla difensiva consentendo incongruenze di ingresso?

È stato utile?

Soluzione

si stanno assumendo che l'ingresso è perfetto. Se si guarda al modo in cui l'applicazione è attualmente messa a punto, Sulla base di una rapida lettura del vostro algoritmo dati sarebbe simile a questa

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

Ma si consideri il caso

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

In base a vostro algoritmo, ora avete 2 canzoni caratterizzato da

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

Con l'algoritmo corrente, l'artista e il titolo sono esposti e apparirà nella seconda canzone, anche se non sono stati definiti. È necessario reimpostare le tre variabili.

nel vostro altro si sono solo dumping La linea completa in testi. Che cosa succede se si aveva già tirato fuori della canzone, si sono ora ignorando. Test case

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

Consideriamo l'invio di questo record per uno stato di errore. Così, quando la lettura batch è completato, un rapporto di errore può essere generato e fissato.

Inoltre si considera solo EOF dopo un artista è stato letto. Che se l'EOF si verifica durante l'Artista leggere, e il file non termina in". Si sta per ottenere un'eccezione lì. Nel vostro do / while aggiungere un altro verificare la presenza di hasNextLine ()

Altri suggerimenti

Vorrei sostituire per esempio:.

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

con

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

Le altre modifiche comprendono:

  1. ripristinare le variabili locali (in modo da non accidentalmente ottiene l'artista sbagliato per una canzone, se nessun artista è fornito per qualche canzone dopo la prima)
  2. decidere cosa fare se alcuni dati mancano -? Vuoi ancora per aggiungere il brano alla lista canzone

Nel mondo reale, ci sono alcune garanzie compiuti per quanto riguarda l'integrità dei dati. Nel caso di trattare con l'input dell'utente (sia dallo stdin o da un file) c'è qualche progetto paradigma definito per avvisare l'utente di un problema che richiede attenzione.

Per esempio, quando un codice compilazione compilatore o un guscio di esecuzione di uno script incontra una contraddizione potrebbe fermare e stampare la riga contenente l'incoerenza con una seconda linea di sotto di essa che utilizza il simbolo "^" per indicare la posizione del problema .

Quindi, ecco alcuni domanda fondamentale da porsi:
1. È ogni linea garantito per contenere tutti i campi?
2. È l'ordinamento dei campi garantiti?

Se queste sono le condizioni del contratto di ingresso e sono violati, si dovrebbe ignorare / segnalare la linea. Se non sono le condizioni dell'ingresso, allora avete bisogno di gestire la cosa .. che attualmente non.

Vedo un paio di cose che mancano qui Jason.

Credo che il if / else era soddisfacente e non cambierà la logica. Tuttavia, si dovrebbe limitare l'ambito delle variabili, per quanto possibile. Dichiarando artista, titolo, ecc all'interno del ciclo while, saranno inizializzati a null (o qualsiasi altra cosa), quindi se una voce non è presente l'artista allora non ottenere il valore dell'ultimo ingresso.

Inoltre, cosa succede se titolo, artista, ecc ha un preventivo in esso? Come è che ha gestito? Come circa la canzone che sembrano essere più righe giusto?

Che cosa succede se c'è un campo sconosciuto - forse un errore di ortografia? Sarà aggiunto alla fine della canzone, che non mi sembra giusto. Solo una volta il campo delle canzoni è stato trovato si dovrebbe aggiungere ad esso. Se testi è nullo allora inizierà con "null".

Qui ci sono alcune questioni che potrebbero essere affrontate:

  • Il codice si presuppone che non ci sia spazio bianco prima (per esempio) "ARTIST", nessuno in tutto il segno "=" e così via.

  • Il codice presuppone che le parole chiave sono in tutto in maiuscolo. Qualcuno potrebbe usare lettere minuscole o miste.

  • Il codice si presuppone che una linea che non inizia con keyword=\" è una continuazione del testo della canzone. Ma cosa succede se l'utente ha immesso ARTOST="Sting"? O che cosa se l'utente ha tentato di utilizzare due linee per il nome di un artista?

Infine, mi sono convinto che la sostituzione di "else if" con "se" in questo caso ha fatto alcuna differenza per la robustezza del codice.

Deal con le eccezioni (immagino scanner potrebbe gettare InputMismatchException per un carattere non valido).

Sembra che il ciclo do { } while (...) lattina senza fine se il file è mal formato, e si raggiunge la fine del file.

impedisce Niente artist o title dall'essere vuota.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top