Ayuda con ejercicio escolar sobre arrays
Hola,
Primero que nada quiero darme unas lineas para felicitar este foro y la pagina en general, siento que tendre mucho uso de ella ya que estoy estudiando Java y varias cosas que no encuentro en los libros y apuntes que recomiendan en la Universidad.
A proposito de lo mismo me he complicado de manera increible con el ultimo ejercicio de la primera parte del curso de Java. El ejercicio consiste en leer un archivo de texto y crear arrays a partir de él para finalmente mostrarlos ordenados alfabeticamente.
El archivo de texto esta creado de la siguiente manera:
Elvis_Presley Jailhouse_Rock Rock RCA 1991 17 72,23
Massive_Attack Protection
Massive_Attack Blue_Lines
Test_Iscicles Circle_Square_Triangle Ska NoLabel 1995 2 9,12
Cada linea de este archivo representara un array (o un CD) y cada pieza de infromacion de cada linea es un elemento del array, asi por ejemplo si tomo la segunda linea del archivo (el segundo array) el array seria:
array2[0] = Massive_Attack
array2[1] = Protection
Para leer este array he creado una clase llamada Labb4 que se ve como sigue:
-
import java.io.*;
-
import java.util.Scanner;
-
-
public class Labb4 {
-
-
-
try {
-
-
String textLines;
-
while ((textLines = lineReader.readLine()) != null) {
-
-
-
}
-
-
-
lineReader.close();
-
}
-
}
-
}
En esta clase estoy inicializando un array con 10 posiciones tan solo para probar. Luego leo el documento de texto, separo cada pieza de informacion y les asigno un nombre de variable. En este punto debo crear un objeto de la clase CD con los datos leidos en el while y luego agregar este objeto en un array.
Para ordenar alfabeticamente los arrays se debe utilizar un metodo llamado "sort" que se encuentra en una clase llamada CD, esta es una clase que fue utilizada en un ejercicio anterior y se debe volver a utilizar. Esta clase se ve de la siguiente manera:
-
/*
-
* To change this template, choose Tools | Templates
-
* and open the template in the editor.
-
*/
-
-
/**
-
*
-
* @author Americo Perez
-
* @date 16-11-2010
-
* @kurs Java I (dt006g)
-
* @Labb Laboration 2
-
*
-
*/
-
public class CD {
-
private double playTime;
-
private int releaseYear, numberSongs;
-
-
public CD() {
-
-
}
-
-
-
//Constructor for the cd with brief information
-
this.artist = artist;
-
this.title = title;
-
this.releaseYear = releaseYear;
-
}
-
-
-
//Constructor for the cd with full information
-
this(artist, title, releaseYear);
-
this.genre = genre;
-
this.recordLabel = skivbolag;
-
this.releaseYear = releaseYear;
-
this.numberSongs = numberSongs;
-
this.playTime = playTime;
-
}
-
-
-
//Array Sortering
-
public sort(CD[] skivor) {
-
-
// Aqui tengo que ordenar el array alfabeticamente
-
-
}
-
-
-
-
-
//Setting and getting the information from Labb2.java class
-
-
nothing = empty;
-
}
-
-
return nothing;
-
}
-
-
artist = name;
-
}
-
-
return artist;
-
}
-
-
title = titleName;
-
}
-
-
return title;
-
}
-
-
genre = genreName;
-
}
-
-
return genre;
-
}
-
-
recordLabel = recordLabelName;
-
}
-
-
return recordLabel;
-
}
-
-
public void setReleaseYear(int releaseDate) {
-
releaseYear = releaseDate;
-
}
-
-
public int getReleaseYear() {
-
return releaseYear;
-
}
-
-
public void setNumberSongs(int songsNumber) {
-
numberSongs = songsNumber;
-
}
-
-
public int getNumberSongs() {
-
return numberSongs;
-
}
-
-
public void setPlayTime(double cdPlayTime) {
-
playTime = cdPlayTime;
-
}
-
-
public double getPlayTime() {
-
return playTime;
-
}
-
-
-
//Create the printBrief metod which will print some information.
-
public void printBrief() {
-
System.out.println("Artist : " + getArtist() + "\nAlbums namn : " + getTitle() + "\nUtgivningsår: " + getReleaseYear());
-
}
-
-
//Create the printFull metod which will print all the information.
-
public void printFull() {
-
System.out.println("Artist : " + getArtist() + "\nAlbums namn : " + getTitle() + "\nGenre : " + getGenre() + "\nSkivbolag : " + getSkivbolag() + "\nUtgivningsår: " +
-
getReleaseYear() + "\nAntal låtar : " + getNumberSongs() + "\nSpeltid : " + getPlayTime() + " minuter.");
-
}
-
}
Mi problema es como crear el CD objeto en la clase Labb4 y agregarlo al array y despues como lo ordeno en el metodo "sort".
Otra exigencia del ejercicio es que los arrays ordenados alfabeticamente deben ser escritos a un nuevo archivo de texto. Pero quiero pensar en este ultimo paso una vez que haya solucionado lo anterior.
Dos restricciones son que no se puede utilizar Arrays.sort o Collections.sort
Cualquier idea, ejemplo, lo que sea se los agradecere. Realmente no encuentro como resolver este ejercicio.
Antemano muchas gracias
//Americo
- Inicie sesión o regístrese para enviar comentarios
Para agregar elementos a un arreglo.
Si te fijas en la linea 33 de la clase CD tienes un constructor que recibe todos los datos necesarios para crear el objeto, y en la línea 18 de Labb4 ya tienes todos los datos.
Entonces, basta con que lo invoques:
CD cd = new CD( artist, title genre ...etc. ec
...
Si no tienes toda la información puedes dejar algunos datos en nulo.
CD cd = new CD( artist, null, genre, null , ...etc. ec
...
Otra opción es crear el objeto y "settear" los valores que si tengas:
cd.setArtist( textFile.next());
cd.setAlbum(textFile.next());
cd.setGenre(textFile.next());
cd.setLabel(textFile.next());
Luego ( o antes ) tendrías que cambiar el tipo de tu arreglo, por que ahora mismo es de strings y tu necesitas que sea de CD's
En la linea 7
...
Y agregarlo:
...
array[ i ] = cd; // coloca el nuevo objeto cd en la posición "i"
Obvio tienes que crear e incrementar la variable i, ahi te queda de ejercicio esa parte.
Para el ordenamiento:
En la línea 44 de CD ya está definido la firma del método de ordenamiento:
( en mi opinión debería de ser un método de clase :
public static sort( CD[] skivor )
)Luego lo que tienes que hacer es implementar algún algoritmo de ordenamiento. El más sencillo es "bubble sort" o de burbuja.
En la Wikipedia viene un ejemplo en Java utilizando números. Lo que lo hace más interesante es que tu tienes que ordenar CD's, bajo algún criterio y no números. Para entender como funcionaría y como podrías hacer este ordenamiento con algún elemento no numérico ( que puede ser comparado con el operador > ) revisa mi explicación en una pregunta similar.
Haz un intento, y postea de nuevo con lo que tengas y donde te estas otorando.
Me he quedado atorado
Gracias por tu tiempo, en realidad necesito una ayuda con esto,
En realidad un poco atorado. He aplicado los consejos que me has dado pero hay algo que no quiere funcionar.
Mi clase Lab4 se ve de esta manera ahora:
import java.util.Scanner;
public class Labb4 {
public static void main(String args[]) {
CD[] myArray = new CD[10];
try {
BufferedReader lineReader = new BufferedReader(new FileReader("skivor.txt"));
String textLines;
while ((textLines = lineReader.readLine()) != null) {
for (int index = 0; index < myArray.length; index++) {
Scanner textFile = new Scanner(lineReader);
CD cd = new CD();
cd.setArtist(textFile.next());
cd.setTitle(textFile.next());
cd.setGenre(textFile.next());
cd.setSkivbolag(textFile.next());
cd.printArray();
myArray[index] = cd;
} // end for
} // end while
lineReader.close();
} catch (IOException ioe) {
System.out.println("Error de lectura del archivo");
}
} // end Main
}
para probarla he creado un objeto llamado "printArray" en la clase CD que solamente imprime los "get", sin mensajes de textos o similares.
Pero el resultado esta lejos de ser lo esperado. Al probar la clase la primera linea del archivo de texto no se imprime, la segunda y tercera linea se imprimen como si fuera una sola y la cuarta tampoco se imprime.
Esto es lo que me entrega la consola:
Massive_AttackProtectionMassive_AttackBlue_Lines
at java.util.Scanner.throwFor(Scanner.java:838)
at java.util.Scanner.next(Scanner.java:1347)
at Labb4.main(Labb4.java:29)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
Cual es el problema??
Estoy leyendo tu post sobre el argoritmo de ordenamiento, tan pronto solucione este problema pondre en practica lo que escribes en el post.
/Americo
El problema no estuvo en la
El problema no estuvo en la impresión, sino en que quisiste leer un elemento que no existe , quizá tu archivo no tiene todos los datos. Al menos eso es lo que dice tu stacktrace
Massive_AttackProtectionMassive_AttackBlue_Lines
at java.util.Scanner.throwFor(Scanner.java:838)
at java.util.Scanner.next(Scanner.java:1347)
at Labb4.main(Labb4.java:29) <------------------------------------------- AQUI
Dice que en la linea 29 invocaset el métod next de Scanner y que no había el elemento que buscabas.
En fin, como alternativa puedes sobrescribir el método "toString()" de la clase CD y temporalmente usar el método toString de la clase Arrays
...
public String toString() {
return "CD[ titile:"+title+", artist:"+artist+"]"; // etc. etc
}
...
Y luego :
Itera todo el arreglo e imprime sus valores
Mmmmm......
No se si estoy cansado o ya se me esta acabando la capacidad de comprension.
No tengo ningun metodo toString en la clase CD y lo otro es que en el archivo de texto no todas las lineas (o cd) contienen la misma informacion. En lagunos casos tiene nombre, titulo, tiempo de reproduccion y en otras solamente nombre y titulo.
Massive_Attack Protection
Massive_Attack Blue_Lines
Test_Iscicles Circle_Square_Triangle Ska NoLabel 1995 2 9,12
Por lo que la clase lab4 deberia ser capaz de diferenciar que informacionn imprimira por cada array.
/Americo
Precisamente, la sugerencia
Precisamente, la sugerencia es que lo tuvieras. En fin, el problema está en que en cada CD ( en cada linea ) tu esperas encontrar exactamente el mismo número de campos.
edit Un momento, me parece que está batiendo todo. En la linea 13 de Labb4, estas creando un Scanner con todo el archivo y en la linea 12 estas iterando todo el archivo.
Debes de crear un Scanner con la linea actual solamente.
Aún así, si tienes un número disparejo de elementos por línea el scanner fallará, mira:
class ScannerDemo {
public static void main( String [] args ) {
// la linea tiene 2 elementos y se intentarán leer 3
Scanner s = new Scanner("a b");
s.next();
s.next();
s.next();
}
}
Al correrlo:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at ScannerDemo.main(ScannerDemo.java:7)
Te parece conocido?
OK, no hope
Voy a comenzar todo de nuevo desde cero, Estoy muy confundido y creo que es mejor partir desde cero nuevamente.
A medida que vaya creando algo nuevo ire posteandolo para conocer tus comentarios.
/Americo
Aqui esta el codigo reescrito
He reescrito la clase Lab4 y me he encontrado con el primer problema.
import java.util.Scanner;
public class Labb4 {
public static void main(String args[]) {
CD[] myArray = new CD[4];
File file = new File("skivor.txt");
try {
Scanner lineReader = new Scanner(file);
while (lineReader.hasNextLine()) {
String textLine = lineReader.nextLine();
for (int row = 0; row < myArray.length; row++) {
Scanner line = new Scanner(textLine); // el problema es aqui!!!
CD cd = new CD();
cd.setArtist(line.next());
cd.setTitle(line.next());
cd.printArray();
}
}
lineReader.close();
} catch (IOException ioe) {
System.out.println("Error de lectura del archivo");
}
} // end Main
}
Con este codigo obtengo los arreglos pero mal iterizados.
Elvis_PresleyJailhouse_Rock
Elvis_PresleyJailhouse_Rock
Elvis_PresleyJailhouse_Rock
Elvis_PresleyJailhouse_Rock
Massive_AttackProtection
Massive_AttackProtection
Massive_AttackProtection
Massive_AttackProtection
Massive_AttackBlue_Lines
Massive_AttackBlue_Lines
Massive_AttackBlue_Lines
Massive_AttackBlue_Lines
Test_IsciclesCircle_Square_Triangle
Test_IsciclesCircle_Square_Triangle
Test_IsciclesCircle_Square_Triangle
Test_IsciclesCircle_Square_Triangle
BUILD SUCCESSFUL (total time: 0 seconds)
El problema esta en la linea:
Scanner line = new Scanner(textLine);
Si no me equivoco el parametro del Scanner deberia ser "row" ya que es row quien tiene la linea actual, pero al intentar usar "row" Netbeans me reclama diciendo que no puede encontrar el constructos Scanner(int).
Por que y como puedo solucionar este problema?
A proposito, he simplificado el archivo de texto y ahora tiene solamente nombre de artista y album. Todas las lineas tienen la misma cantidad de informacion
mas adelante agregare mas informacion en el archivo y vere como se comporta la clase.
/Americo
Por lo que entiendo, dentro
Por lo que entiendo, dentro de tu arreglo, deberías descomponer la línea por "tokens"
lo puedes hacer con
StringTokenizer
otextLine.split( )
, con eso sacarías un arreglo de Strings, donde cada tokenrepresentaría una propiedad de tu CD ...
String textLine = lineReader.nextLine();
String [ ] cdTags = textLine.split( /*aquí va el separador que usas, underscore, o espacio en blanco*/ );
CD cd = new CD();
cd.setArtist( cdTags[ 0 ] );
cd.setTitle( cdTags[ 1 ] );
cd.printArray();
}
Digo, es a primera instancia lo que se me ocurre, aunque si crecen las propiedades de tu CD, pues sería poco práctico hacerlo así...
Si no me equivoco el
Si no me equivoco el parámetro del Scanner debería ser "row" No, fíjate en el tipo de dato de row
int row = 0
es un int. Es decir, es el índice de la linea y no la linea misma, por eso no te funciona el Scanner, no hay un constructor que reciba un int. Entonces por ahi no esta el problema.Que notas de raro en la salida? Están cuatro veces todas las entradas no? Lo que no se vé en el código que pusiste, es, como estas agregando el CD al arreglo, ni como haces la impresión.
Se me hace que estas agregando siempre a la misma parte.
Aprovechando que limpiaste tu
Aprovechando que limpiaste tu código lo suficiente como para poder correrlo yo mismo, corrí y ya entendí por que te está saliendo esto.
Son dos problemas, bueno uno es un problema y otro es una vision :P
El primer problema es que estás leyendo cada linea, lo cual esta bien, pero luego estas queriendo llenar esa linea en las 4 posiciones del arreglo.
Entonces lo que ahorita estas haciendo ( mal ) es:
1.- Lees la linea: Elvis_Presley Jailhouse_Rock
2.- Iteras todo el arreglo ( ahí es donde esta realmente el horror )
2.0.- Para la posición 0 imprimes Elvis_PresleyJailhouse_Rock
2.1.- Para la posición 1 imprimes Elvis_PresleyJailhouse_Rock
2.2.- Para la posición 2 imprimes Elvis_PresleyJailhouse_Rock
2.3.- Para la posición 3 imprimes Elvis_PresleyJailhouse_Rock
Repites el paso 1 ahora con Massive_AttackProtection
Por eso te salen cada uno cuatro veces.
El segundo problema es que imprimes cada vez que estas llenando el elemento, pero jamás lo pones en el arreglo, lo que tienes que hacer es imprimir despues y agregarlo al arreglo.
Modifiqué tu código y lo siguiente ya funciona bien. Te puse comentarios esperando que entiendas cuales fueron las diferencias.
Saludos!!!
Entonces si te fijas, ya estabas bastante cerca. Comenté todos los cambios para que te pudieras dar cuenta de las diferencias, borralos cuando los hayas ( y hasta ) que los hayas entendido. Finalmente, no le moví mucho a tu código así que no cuenta como que te hice la tarea y aún te falta bastaaaante camino por recorrer.
Espero que te sirva.
Suerte!
Ahora estoy mas cerca
Gracias por el tip.
He insertado el textLine.split y he eliminado el for. Ahora obtengo los arreglos como deberia ser.
Aqui esta el codigo actualizado:
import java.util.Scanner;
public class Labb4 {
public static void main(String args[]) {
File file = new File("skivor.txt");
try {
Scanner lineReader = new Scanner(file);
int arrayNumber = 0;
while (lineReader.hasNextLine()) {
// Crea un array de tipo CD. arrayNumber determina el tamano del array
CD[] myArray = new CD[arrayNumber];
String textLine = lineReader.nextLine();
Scanner row = new Scanner(textLine);
String[] cdTags = textLine.split(" ");
// Crear el objeto CD por cada arreglo (cada linea en el archivo de texto)
CD cd = new CD();
cd.setArtist(row.next());
cd.setTitle(row.next());
// Llama al metodo printArray para mostrar los arrays
cd.printArray();
arrayNumber++;
}
//Cierra el archivo de texto
lineReader.close();
} catch (IOException ioe) {
System.out.println("Fel inläsning");
}
} // end Main
}
Ahora lo que necesito hacer es ordenarlos alfabeticamente y para eso debo utilizar el metodo "sort" de la clase CD que es de la siguiente manera:
/*
sorting goes here
*/
}
Necesitaria un empujencito para saber como "traspaso" los arreglos a este metodo para aplicar el algoritmo de ordenamiento que OscarRyz me recomendo estudiar.
OscarRyz: Ahora me esta entregando de forma correcta los arreglos en la consola:
Front_Line_Assembly Mindphaser
Elvis_Presley Jailhouse_Rock
Massive_Attack Protection
Massive_Attack Blue_Lines
Test_Iscicles Circle_Square_Triangle
BUILD SUCCESSFUL (total time: 0 seconds)
Para tener mas informacion: el metodo printArray es asi:
System.out.println(getArtist() + " " + getTitle() + "\n");
}
/Americo
No uses split y Scanner al mismo tiempo
Solo estás revolviendo las cosas. Split es bueno, pero el scanner hace precisamente eso. Si te fijas en tu código no usaste para nada el resultado del split, asi que mejor quitalo.
Para pasarlo solo necesitas antes de que termine el main:
Pero claro, necesitas que sort sea un método de clase
public static sort( CD [] arreglo )
( no tiene sentido que sea de instancia a menos claro que lo que quieras sea ordenar los elementos internos , en fin )Ya casi lo haces. Revisa
java.lang.String.compareTo()
para saber como hacer una comparacion alfanumerica de strings. Ejemplo:Gracias por el aviso!!
lo que necesito hacer con sort es ordenar los arreglos y guardarlos en un archivo de texto.
/Americo
Ahh pues ahi si ya aplica lo
Ahh pues ahi si ya aplica lo del bubble sort :)