Foro de elhacker.net

Programación => Java => Mensaje iniciado por: |Miguel| en 19 Octubre 2011, 20:10 pm



Título: [RESUELTO] Desesperado...{pasar una frase a un array, una palabra por poscion}
Publicado por: |Miguel| en 19 Octubre 2011, 20:10 pm
Hola, buenas a todos..
Bien, empecé hace una semanita en Java y hay un ejercicio de clase que no soy capaz de resolver.

No quiero la respuesta, quiero entender por qué falla mi código y una orientación para ir adelante, un empujoncito.

Bien ahí van el enunciado y mi ridículo código... XD

Hacer un vector que guarde una frase, de forma que cada palabra ocupe una posición, y luego las mostramos una por línea. Sin espacios.

Código
  1. package ejercicio021;
  2.    import java.util.Scanner;
  3. public class Ejercicio021 {
  4.    public static void main(String[] args) {
  5.        //Hacer un vector que guarde una frase, de forma que cada palabra
  6.        //ocupe una posición, y luego las mostramos una por línea. Sin espacios.
  7.        int i, pos_espacio=0, palabras=0 , prim=0;
  8.        Scanner s=new Scanner(System.in);
  9.        String frase=new String();
  10.        System.out.println("Introduzca frase:");
  11.        frase=s.nextLine();
  12.        frase=frase.trim();
  13.  
  14.        do{ //este bucle sirve para contar las palabras que tiene la frase y hacer un array con las posiciones justas
  15.            if ( frase.indexOf(" ", pos_espacio)>0 || frase.length()>0 ) palabras++;
  16.            pos_espacio=frase.indexOf(" ", pos_espacio)+1;
  17.            //System.out.println(palabras + " " +espacios+" "+pos_espacio);
  18.            //La línea de arriba es solo para comprobar que iba bien.
  19.        }while(pos_espacio>0);
  20.        //*********************************************************************
  21.        //System.out.println("Palabras: "+palabras);
  22.        String vector[]=new String[palabras];
  23.        pos_espacio=frase.indexOf(" ", 0)+1;
  24.  
  25.        //y a partir de aquí nada funciona..
  26.        for(i=0; i<palabras; i++){
  27.            System.out.print("i="+i+" prim="+prim+" pos_espacio="+pos_espacio+"--");
  28.            vector[i]=frase.substring(prim, pos_espacio-1);
  29.            prim=pos_espacio;
  30.            pos_espacio=frase.indexOf(" ", pos_espacio+1)+1;
  31.            System.out.println(vector[i]);
  32.    }
  33. }

Para la frase Hoy es miércoles obtengo el siguiente resultado:
Citar
run:
Introduzca frase:
Hola hoy es miércoles.
i=0 prim=0 pos_espacio=5--Hola
i=1 prim=6 pos_espacio=9--oy
i=2 prim=10 pos_espacio=12--s
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -14
   at java.lang.String.substring(String.java:1938)
   at ejercicio021.Ejercicio021.main(Ejercicio021.java:26)
i=3 prim=13 pos_espacio=0--Java Result: 1


Título: Re: Desesperado...{pasar una frase a un array, una palabra por poscion}
Publicado por: Valkyr en 19 Octubre 2011, 23:11 pm
Si en el ejercicio no te pone ninguna limitación podrías hacer uso del método split() de la clase String. La cosa sería, lees la cadena de teclado guardandola en un String, aplicas el método split() que te devuelve un array de cadenas.

El parametro de la función es una expresión regular.

El código que te propongo sería algo así:

Código
  1. String linea = escaner.nextLine();
  2. linea = linea.trim();
  3. String[] vector = linea.split(" +");

Luego recorres ese array y listo. El parámetro (" +") representa uno o más espacios, por tanto, aunque las palabras estén separadas por muchos espacios en cada posición del array solo tendrás una cadena de caracteres.

El error me imagino que te lo da por hacer esto: (" ", pos_espacio+1)+1, estás avanzando siempre un caracter, en algún momento te saltas alguna palabra, llegas antes al final, te devuelve -1 e intentas acceder con un -1 en la función substring.

Saludos.


Título: Re: Desesperado...{pasar una frase a un array, una palabra por poscion}
Publicado por: |Miguel| en 19 Octubre 2011, 23:15 pm
me gusta bastante esa solución, aunque no hemos visto en clase el método split() y supongo que el profesor querrá que lo hagamos a mano. Intentaré eso a ver que me sale,
gracias :)

EDITO: aunque voy a seguir investigando con split, he conseguido hacerlo funcionar de la otra forma. efectivamente el error venía por que en la ultima palabra me iba de rango e intentaba acceder a posiciones de string que no existían. esta es la corrección:
Código
  1. package ejercicio021;
  2.    import java.util.Scanner;
  3. public class Ejercicio021 {
  4.    public static void main(String[] args) {
  5.        //Hacer un vector que guarde una frase, de forma que cada palabra
  6.        //ocupe una posición, y luego las mostramos una por línea. Sin espacios.
  7.        int i, j, pos_espacio=0, palabras=0 , prim=0;
  8.        Scanner s=new Scanner(System.in);
  9.        String frase=new String();
  10.        System.out.println("Introduzca frase:");
  11.        frase=s.nextLine();
  12.        frase=frase.trim();
  13.        do{
  14.            if ( frase.indexOf(" ", pos_espacio)>0 || frase.length()>0 ) palabras++;
  15.            pos_espacio=frase.indexOf(" ", pos_espacio)+1;
  16.            //System.out.println(palabras + " " +espacios+" "+pos_espacio);
  17.            //La línea de arriba es solo para comprobar que iba bien.
  18.        }while(pos_espacio>0);
  19.        //*********************************************************************
  20.        //System.out.println("Palabras: "+palabras);
  21.        String vector[]=new String[palabras];
  22.        pos_espacio=frase.indexOf(" ", 0)+1;
  23.  
  24.        if (palabras==1)
  25.            vector[0]=frase;
  26.        else
  27.            for(i=0; i<palabras; i++){
  28.               //System.out.println("i="+i+" prim="+prim+" pos_espacio="+pos_espacio+"--"); //comprobaciones
  29.               vector[i]=frase.substring(prim, pos_espacio-1);
  30.               prim=pos_espacio;
  31.               if(frase.indexOf(" ", pos_espacio)!=-1) pos_espacio=frase.indexOf(" ", pos_espacio+1)+1;
  32.               else pos_espacio= frase.length()+1;
  33.            }
  34.        for(i=0; i<palabras; i++) System.out.println(vector[i]);
  35.    }
  36. }


por cierto, vuestros códigos aparecen con colores y el mio no, ¿usais una etiqueta distinta de 'code', o lo haceis a mano?


Título: Re: Desesperado...{pasar una frase a un array, una palabra por poscion}
Publicado por: s00rk en 20 Octubre 2011, 00:20 am
Para que la sintaxis resalten, solamente en la etiquetra code agregale =lenguaje, ejemplo code=java , claro en los corchetes n_n

Sobre el trabajo pues si como dice Valkyr , usando el metodo split de la Clase String te ayuda y reduce bastante todo jeje
Código
  1. Scanner leer = new Scanner(System.in);
  2. System.out.println("Frase: ");
  3. String frase = leer.nextLine();
  4. String [] arr = frase.split(" +");
  5. for(String palabra: arr)
  6. System.out.println(palabra);
  7.  


Título: Re: Desesperado...{pasar una frase a un array, una palabra por poscion}
Publicado por: |Miguel| en 21 Octubre 2011, 19:27 pm
No entiendo ese for. He hecho una version con split, y da un pequeño fallo. De momento os dejo esto aqui, hasta que la corrija.

En esta versión, he puesto un array no dinámico porque no tenía mucho tiempo y me es más rápido, pero eso es cojer la parte de contar palabras de abajo y darle al array ese tamaño.
Código
  1. public static void main(String[] args) {
  2.        String frase=new String();
  3.        Scanner s=new Scanner(System.in);
  4.        System.out.print("Introduce frase: ");
  5.        frase=s.nextLine();
  6.  
  7.        String []miArray=new String[50];
  8.        miArray=frase.split(" +");
  9.  
  10.        for(int i=0; i<50; i++){
  11.            System.out.println(miArray[i]);
  12.        }
  13.    }

Cita de: NetBeans
run:
Introduce frase: hola pepe viñuelas
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
hola
pepe
vi�uelas
   at javaapplication1.JavaApplication1.main(JavaApplication1.java:16)
Java Result: 1
BUILD SUCCESSFUL (total time: 6 seconds)


Título: Re: [RESUELTO] Desesperado...{pasar una frase a un array, una palabra por poscion}
Publicado por: Valkyr en 21 Octubre 2011, 21:44 pm
No necesitas crear una nueva instancia del array, el propio método split te devuelve el objeto ya instanciado.

El bucle for que dices que no entiendes es un bucle "for each" es decir, para cada uno de los elementos del array hacer...lo que sea.

Te dejo una referencia a Wikipedia por si quieres echar un vistazo:

http://en.wikipedia.org/wiki/Foreach_loop#Java (http://en.wikipedia.org/wiki/Foreach_loop#Java)

Basandome en tú código y con la modificación que te he dicho quedaría así:

Código
  1. public static void main(String[] args) {
  2.        String frase=new String();
  3.        Scanner s=new Scanner(System.in);
  4.        System.out.print("Introduce frase: ");
  5.        frase=s.nextLine();
  6.  
  7.        String []miArray;
  8.        miArray=frase.split(" +");
  9.  
  10.        for(String palabra : miArray){
  11.            System.out.println(palabra);
  12.        }
  13.    }

Saludos.


Título: Re: [RESUELTO] Desesperado...{pasar una frase a un array, una palabra por poscion}
Publicado por: |Miguel| en 22 Octubre 2011, 12:23 pm
Vale, si no uso las funciones como hay q usarlas normal q no me salgan las cosas  :xD

Muchas gracias. Lo del for each es bastante interesante, no sabía que existía.