Autor Tema: Java duda sobre valores de los índices en un ciclo for cuál es último CU00661B  (Leído 4378 veces)

adrit

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 59
    • Ver Perfil
Hola, quisiera consultar acerca del siguiente código, ya que no entiendo porque el uso de - 1 en i < entradaTeclado.length() - 1

Código: [Seleccionar]

for (int i=0; i < entradaTeclado.length() - 1; i++) {
            if (entradaTeclado.substring (i, i+1).equals(" ") ) {     //IMPORTANTÍSIMO: COMPARAMOS CON EQUALS
                return entradaTeclado.substring(0, i+1);         }

Probé no agregarlo a mi código y el resultado fue el mismo.

Desde ya muchas gracias.

Saludos
« Última modificación: 16 de Julio 2015, 12:08 por Alex Rodríguez »

RaGa

  • Moderador Global
  • Intermedio
  • *******
  • APR2.COM
  • Mensajes: 234
    • Ver Perfil
Re:Consulta sobre ejemplo de ejercicio (CU00661B)
« Respuesta #1 en: 10 de Julio 2015, 15:09 »
Hola Adrián:

Muy interesante tu observación. Analicemos:
Esa parte del código que copias lo que hará será devolver la primera palabra si es que la cadena que estamos ingresando tiene 2 o más palabras separadas por un " " entre si.
Si la cadena solo fuera una palabra (sin espacios " " internos) se devuelve la palabra completa.
Ejemplo:
Si una de las cadenas ingresadas fuese: "Automovil", el método getPrimeraPalabra() devolverá "Automovil".
Pero si la cadena ingresada fuese: "Motocicleta Deportiva", el método getPrimeraPalabra() devolverá "Motocicleta".

Respecto al uso de -1 en el límite del ciclo for. Reescribamos:
Código: [Seleccionar]
for (int i=0; i < entradaTeclado.length() - 1; i++) {

            if (entradaTeclado.substring (i, i+1).equals(" ") ) {     //IMPORTANTÍSIMO: COMPARAMOS CON EQUALS

                return entradaTeclado.substring(0, i+1);         
            }
}

Supongamos que ingresamos la cadena "Hola", por lo tanto al campo entradaTeclado tipo String se le asigna la cadena "Hola".

¿Y qué valor devuelve el método entradaTeclado.length() ? Respuesta: 4

Vayamos haciendo las distintas valuaciones del método entradaTeclado.substring (i, i+1)
Conforme "i" vaya tomando distintos valores tendremos (comenzando por el 0):

entradaTeclado.substring (0, 0+1) = "H"
entradaTeclado.substring (1,1+1) = "o"
entradaTeclado.substring (2,2+1) = "l"
entradaTeclado.substring (3, 3+1) = "a"

Fíjate que con la variable "i" valiendo 3, ya se ha recorrido cada caracter de la cadena.
Si le permitiera a "i" valer 4, me daría un error, ¿por qué? porque el método:

entradaTeclado.substring (4, 4+1) estaría accediendo a una posición inexistente (la posición 5).

Conclusión: no puedo permitir que "i" llegue a valer 4, es decir, que "i" puede tener como límite superior el valor: entradaTeclado.length() - 1

En este ejercicio, nunca se alcanza esa condición, por lo que bien tu dices no incluyendo el -1 no se produce ningún cambio.

Sin embargo te propongo reescribr el método de la siguiente manera para que puedas comprobar que ese -1 debe existir para no obtener un error en tiempo de ejecución.

Código: [Seleccionar]
    public String getPrimeraPalabra ()  {

       /*IMPORTANTE: EN JAVA LOS OBJETOS NO SE PUEDEN COMPARAR USANDO == POR ESO ESTO NO FUNCIONARÁ       

          if (entradaTeclado.substring(0,1)=="j") {

          System.out.println ("Hemos detectado una j");

          } else { System.out.println ("Mira esto:" + entradaTeclado.substring(0,1) ); }*/ 
       
        int i = 0;
        for (i=0; i < entradaTeclado.length() ; i++) {

            if (entradaTeclado.substring (i, i+1).equals(" ") ) {     //IMPORTANTÍSIMO: COMPARAMOS CON EQUALS

                return entradaTeclado.substring(0, i+1);         }

        }

        return entradaTeclado.substring(0, i+1);  //Caso de que no se detecte ningún espacio devolvemos lo que haya

    } //Cierre del método getPrimeraPalabra

Analízalo y cualquier duda estamos quí que reveerlo.

adrit

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 59
    • Ver Perfil
Re:Consulta sobre ejemplo de ejercicio (CU00661B)
« Respuesta #2 en: 10 de Julio 2015, 16:02 »
Estimados RaGa, como siempre muchas gracias por una respuesta tan completa.

Lo que me confunde es que cuando escribo "for (i=0; i < entradaTeclado.length() ; i++) "
entiendo que si el método length() para un ejemplo con String "hola" devuelve 4 como resultado, "i" nunca podría valer 4 ya que, la condición en el for es que "i" debe valer menos que "4" (usando el ejemplo de "hola"). No estoy usando <=.
Es decir, "i" alcanzaria un valor maximo de 3 (for haría 4 pasadas ya que i = 0). Si agrego "- 1" "i" alcanzaría un valor máximo de 2 y no llegaría a recorrer toda la cadena, y por eso no comprendo como el loop for llega hasta el espacio que está al final de "hola"

La prueba con el metodo getPrimeraPalabra sin usar -1 me devuelve la primera palabra sin dar error.

Hay algo que estoy razonando mal y no me puedo dar cuenta que es.
« Última modificación: 16 de Julio 2015, 12:08 por Alex Rodríguez »

RaGa

  • Moderador Global
  • Intermedio
  • *******
  • APR2.COM
  • Mensajes: 234
    • Ver Perfil
Re:Consulta sobre ejemplo de ejercicio (CU00661B)
« Respuesta #3 en: 10 de Julio 2015, 21:19 »
Hola Adrián:

Es correcto lo que dices! Me he confundido yo en mi respuesta anterior:

El ciclo "for (i=0; i < entradaTeclado.length() ; i++) "

asumirá los siguientes valores de "i": 0, 1, 2, y 3 cuando la cadena sea "Hola".
Tienes toda la razón! disculpas por la confusión, se trata de un operador < y no de un operador <=.

Pero vayamos al nudo de nuestro problema y para eso retomemos el código original de la clase, que es el que se publica en la lección:

Código: [Seleccionar]
import java.util.Scanner; //Importación del código de la clase Scanner desde la biblioteca Java

// Definimos una clase EntradaDeTeclado aprenderaprogramar.com

public class EntradaDeTeclado {

    private String entradaTeclado; //Variable de instancia (campo) de la clase

 

    public EntradaDeTeclado ()  { //Constructor

        entradaTeclado="";

        pedirEntrada(); //Esto es una llamada a un método interno. Al crear un objeto ejecutamos el método

    } //Cierre del constructor

 

    public void pedirEntrada ()  {  //Método de la clase         

        Scanner entradaEscaner = new Scanner (System.in);

        entradaTeclado = entradaEscaner.nextLine ();     } //Cierre del método pedirEntrada

 

    public String getEntrada () { return entradaTeclado; } //Cierre del método getEntrada

    public String getPrimeraPalabra ()  {

       /*IMPORTANTE: EN JAVA LOS OBJETOS NO SE PUEDEN COMPARAR USANDO == POR ESO ESTO NO FUNCIONARÁ       

          if (entradaTeclado.substring(0,1)=="j") {

          System.out.println ("Hemos detectado una j");

          } else { System.out.println ("Mira esto:" + entradaTeclado.substring(0,1) ); }*/ 

        for (int i=0; i < entradaTeclado.length() - 1; i++) {

            if (entradaTeclado.substring (i, i+1).equals(" ") ) {     //IMPORTANTÍSIMO: COMPARAMOS CON EQUALS

                return entradaTeclado.substring(0, i+1);         }

        }

        return entradaTeclado;  //Caso de que no se detecte ningún espacio devolvemos lo que haya

    } //Cierre del método getPrimeraPalabra

 

    public int getLongitud ()  {  //Método de la clase

        return entradaTeclado.length();

    } //Cierre del método getLongitud

} //Cierre de la clase

Analizaremos primeramente qué sucede cuando ingresamos distintas cadenas por teclado.

Si la cadena ingresada por teclada fuera: "HolaAmigo", revisemos qué sucedería en el ciclo for:

Código: [Seleccionar]
       for (int i=0; i < entradaTeclado.length()-1 ; i++) {
            if (entradaTeclado.substring (i, i+1).equals(" ") ) {
                    return entradaTeclado.substring(0, i+1);         
            }
        }

El valor de entradaTeclado.length()-1 sería 8. Es decir que:
entradaTeclado.substring (i, i+1).equals(" ")
devolverá desde la letra "H" hasta la letra "g". Se compararán todas las letras de la cadena ingresada menos la última (lo cual no sería estrictamente lo correcto).
De todos modos, como no hay ningún caracter " ", nunca será true el condicional if, y por lo tanto el retorno se alcanzará en la línea:

Código: [Seleccionar]
return entradaTeclado;  //Caso de que no se detecte ningún espacio devolvemos lo que haya
Esta línea nos devuelve la cadena "HolaAmigo".
Fíjate que no podemos darnos cuenta si cuando chequeábamos letra por letra, preguntamos por todas ellas (cosa que no sucedió), ya que lo que se imprime por consola es lo que contiene el campo entradaTeclado, que es "HolaAmigo".

Ahora bien, y qué sucedería si la cadena ingresada fuese "HolaAmigo " (termina en un espacio). Analicemos:

El valor de entradaTeclado.length()-1 sería 9. Es decir que:
entradaTeclado.substring (i, i+1).equals(" ")
devolverá desde la letra "H" hasta la letra "o", y se compararán todas las letras de la cadena ingresada menos el espacio final.
Por lo tanto nunca se alcanzaría a chequear que el último caracter es un espacio. El condicional if nunca sería true, y el retorno se alcanzaría también en la línea:

Código: [Seleccionar]
return entradaTeclado;  //Caso de que no se detecte ningún espacio devolvemos lo que haya
y se devuelve la cadena "HolaAmigo ".

Ultimo cadena a analizar: si la cadena ingresada tuviera un caracter " " en una posición intermedia, por ejemplo si la cadena fuese "Hola Amigo".
Cuando "i" sea igual a 4, el condicional if se convierte en true, y el retorno se alcanza ahora en la línea:

Código: [Seleccionar]
return entradaTeclado.substring(0, i+1);
la cadena retornada será: "Hola " (con un espacio luego de la letra "a").

Ahora bien ¿y si modificamos el límite superior del ciclo for codificandolo de la siguiente manera?

Código: [Seleccionar]
       for (int i=0; i < entradaTeclado.length(); i++) {
            if (entradaTeclado.substring (i, i+1).equals(" ") ) {
                    return entradaTeclado.substring(0, i+1);         
            }
        }

Primer caso:
Si la cadena ingresada fuese "HolaAmigo", ahora
entradaTeclado.substring (i, i+1).equals(" ")
devolverá desde la letra "H" hasta la letra "o". Se compararán todas las letras de la cadena ingresada (lo cual sería lo correcto!).
No hay ningún caracter " ", nunca será true el condicional if, y por lo tanto el retorno se alcanzará en la línea:

Código: [Seleccionar]
return entradaTeclado;  //Caso de que no se detecte ningún espacio devolvemos lo que haya
Esta línea nos devuelve la cadena "HolaAmigo".

Segundo caso:
Si la cadena ingresada fuese "HolaAmigo " (con un espacio al final)
entradaTeclado.substring (i, i+1).equals(" ")
devolverá desde la letra "H" hasta el espacio final. El caracter final " ", haría que el condicional if sea true, y por lo tanto el retorno se alcanzará en la línea:

Código: [Seleccionar]
return entradaTeclado.substring(0, i+1);
Esta línea nos devuelve la cadena "HolaAmigo " (con un espacio al final).

Tercer caso:
Si la cadena ingresada fuese "Hola Amigo" (con espacio intermedio), sucedería lo mismo que ya se analizó.

Conclusión:
Si nos guiamos por los resultados que vemos en la consola, es exactamente igual si ese -1 lo incluímos o no en el límite superior del ciclo for. Pero si analizamos el desarrollo de lo que sucede internamente en el código hay diferencias.

En mi opinión personal, yo sacaría el -1 del límite superior del ciclo for. De esa manera internamente sea chequearían cada una de las letras de la cadena ingresada.

adrit

  • Principiante
  • **
  • APR2.COM
  • Mensajes: 59
    • Ver Perfil
Re:Consulta sobre ejemplo de ejercicio (CU00661B)
« Respuesta #4 en: 11 de Julio 2015, 14:15 »
Muy claro ahora.

Gracias!!

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".