Pregunta

Para mis estructuras de datos del proyecto, el objetivo es leer en un archivo que contiene proporcionado más de 10.000 canciones con el artista, el título y la letra claramente marcados, y cada canción está separado por una línea con un solo comillas dobles. He escrito este código para analizar el archivo de texto, y funciona, con una duración de poco menos de 3 segundos para
leer los 422K líneas de texto
crear un objeto canción de Agregar dijo Song a un ArrayList

El código de análisis que escribí es:

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 

Yo estaba hablando con mi profesor de Introducción a Algoritmos sobre el código para este proyecto, y él dijo que yo debería tratar de ser más defensiva en mi código para permitir inconsistencias en los datos proporcionados por otras personas. Al principio yo estaba usando if / else bloques entre el artista, campos Título y Letras, y en su sugerencia que cambiar para secuenciales si las declaraciones. Aunque puedo ver su punto, el uso de este ejemplo de código, ¿cómo puedo estar más a la defensiva en cuanto a permitir a las inconsistencias de entrada?

¿Fue útil?

Solución

Se está asumiendo que la entrada es perfecto. Si nos fijamos en la forma en que su aplicación es actualmente la configuración, la base de una lectura rápida de su algoritmo de los datos se vería así

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

Pero consideremos el caso

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

En función de su algoritmo, ahora tiene 2 canciones caracterizado como

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

Con el algoritmo actual, el artista y el título están expuestos y se mostrará en la segunda canción a pesar de que no se definieron. Es necesario restablecer las tres variables.

en su persona se acaba de dumping La línea completa en letras. Lo que si ya se había retirado a cabo Letras, que ahora está reemplazando. caso de prueba

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

Considere enviar este registro a un estado de error. Por eso, cuando se haya completado la lectura por lotes, un informe de error se puede generar y fija.

También usted sólo tienen en cuenta EOF después de un artista fue leído en. ¿Qué pasa si la EOF se produce durante la artista leer, y el archivo no termina en". Usted va a obtener una excepción allí. En el do / while añadir otro comprobar hasNextLine ()

Otros consejos

Me reemplazar por ejemplo:.

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

con

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

Otras modificaciones incluyen:

  1. restablecer las variables locales (por lo que no obtiene accidentalmente el artista equivocado para una canción, si ningún artista se suministra por alguna canción después de la primera)
  2. decidir qué hacer si algún dato no -? ¿Todavía quieres añadir la canción a la lista de canciones

En el mundo real, hay algunas garantías hechas con respecto a la integridad de datos. En el caso de hacer frente a la entrada del usuario (ya sea de la entrada estándar o un archivo) hay algo de paradigma definido proyecto para notificar al usuario de un problema que requiere atención.

Por ejemplo, cuando un código de compilación compilador o una cáscara de la ejecución de una secuencia de comandos de encuentros una inconsistencia podría detener e imprimir la línea que contiene la incompatibilidad con una segunda línea de más abajo que utiliza el símbolo "^" para indicar la ubicación del problema .

Así que aquí están algunas preguntas básicas que preguntarse:
1. ¿cada línea garantizada para contener todos los campos?
2. ¿Está el orden de los campos garantizado?

Si esas son las condiciones del contrato de entrada y se violan, se debe ignorar / reportar la línea. Si no son las condiciones de la entrada, entonces usted necesita para manejarlo .. que actualmente no lo hace.

Veo un par de cosas que faltan aquí Jason.

creo que la multa si / sino que fue y no va a cambiar la lógica. Sin embargo, se debe restringir el alcance de sus variables tanto como sea posible. Al declarar artista, título, etc. dentro del bucle while, serán inicializadas a cero (o lo que sea) por lo que si falta alguna entrada el artista entonces no va a obtener el valor de la última entrada.

Además, ¿qué ocurre si el título, artista, etc. tiene una cita en ella? ¿Cómo es que manejan? ¿Qué hay de las Letras que parecen ser múltiples líneas derecho?

¿Qué pasa si hay un campo desconocido - tal vez una falta de ortografía? Que se añadirá al final de letras que no parece correcto. Sólo una vez se ha encontrado el campo LETRAS debe adjuntar a la misma. Si la letra es nula, entonces se iniciará con "nula".

Aquí hay algunas cuestiones que podrían abordarse:

  • Su código se supone que no hay espacio en blanco antes (por ejemplo) "ARTISTA", ninguno en todo el signo "=" y así sucesivamente.

  • Su código se supone que las palabras clave son toda en mayúsculas. Alguien podría usar minúsculas o mayúsculas y minúsculas.

  • Su código se supone que una línea que no se inicia con keyword=\" es una continuación de la letra de la canción. Pero lo que si el usuario ha introducido ARTOST="Sting"? ¿Y si el usuario ha intentado utilizar dos líneas para el nombre de un artista?

Por último, no estoy convencido de que la sustitución de "else if" con "si" en este caso tiene hecho ninguna diferencia a la robustez del código.

acuerdo con excepciones (supongo escáner podría lanzar InputMismatchException de un carácter no válido).

Parece que el bucle sin fin do { } while (...) lata si está mal formada en el archivo, y se llega al final del archivo.

Nada impide artist o title de ser vacío.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top